I'm a newbie in Java, I'm trying to sent a byte [] array via socket, but it itself convert my array to string and then sends it. so far it's ok, but the problem is that I need to either receive the message in array type, OR I have to convert the string to array, in order to make the decrypt method be able to decrypt the array (the input of decrypt method must be byte array). how can I do that?
my serverside related code is:
private void IssuingTickets() throws Exception{
String socketUsername = reader.readLine();//rcv username
String socketPassword = reader.readLine();//rcv password
writer.println("Lemme Check!");
Properties prop = new Properties();
prop.load(new FileInputStream("input"));
String fileUsername = prop.getProperty("username");
String filePassword = null;
if (prop.getProperty("password") != null) {
filePassword = prop.getProperty("password");}
if (socketPassword.equals(filePassword)){
String sessionKeyBobKdc = new Scanner(new File("sBOBandKDC")).useDelimiter("\\Z").next();
byte[] ClientTicket = encrypt(sessionKeyBobKdc, filePassword);
System.out.println("clietn ticket = " + ClientTicket+" ArraytoString " + Arrays.toString(ClientTicket));
writer.println(ClientTicket);
String KDCkey = new Scanner(new File("KDCkey")).useDelimiter("\\Z").next();
String UnEncTGT= sessionKeyBobKdc.concat(socketUsername);
byte[] TGT = encrypt(UnEncTGT, KDCkey);
writer.println(TGT);
}else
{writer.println("Please try again later!");}
}
public static byte[] encrypt(String plainText1, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(plainText1.getBytes("UTF-8"));
}
public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return new String(cipher.doFinal(cipherText),"UTF-8");
}
}
the Clientside related code is:
private void recieveTickts() throws IOException, InterruptedException, Exception{
String msg = reader.readLine(); //Lemme check
System.out.println("Server :" + msg);
TimeUnit.SECONDS.sleep(3);
String Sth = reader.readLine(); //please try again
if(Sth.equals("Please try again later!")){
System.out.println(Sth);
System.exit(1);
}else{
ClientTicket = Sth;
String TGT = reader.readLine();
System.out.println("Encrypted key between Client and KDC is " + ClientTicket + " and the TGT is " + TGT);
TimeUnit.SECONDS.sleep(3);
System.out.println("SUCCESSFUL"); }
byte[] b = ClientTicket.getBytes();
System.out.println("b= " + b);
String sessionKeyBobKdc = decrypt(b, Password);
System.out.println(Password + "session key is "+ sessionKeyBobKdc);
}
thanx in advanced guys..
I documented the code to help you out but that is basically a quick and dirty way to never stop listening for data and then also return the received as byte[]. If you don't need to listen at all times just modify this code to stop listening once you received your message
You can make this more dynamic with using parameters for defining the sign that a message is finished etc.
I used a StringBuilder to act as a little buffer. And defined that a message is finished once I receive a LF. Everything else get's put into the "buffer". Additionally I filter out CR since I don't want them in my message.
Socket client;
StringBuilder sb = new StringBuilder();
String result = "";
int c;
try
{
InputStream inputStream = client.getInputStream();
while ( ( c = inputStream.read() ) >= 0 ) // Loop to listen for data until the connection is dead
{
if ( c == 0x0a ) // 0x0a is the hex for a LineFeed ( LF )
{
result = sb.toString(); // put everything you received so far as a final message
sb.delete( 0, sb.length() ); // clear your message "buffer"
}
else if ( c != 0x0d /* <CR> */ ) // Not necessary but it helps keeping the message clear
{
sb.append( (char) c ); // add the received integer as char to the message "buffer"
}
if ( !result.isEmpty() ) // Catch that a message is received
{
log.fine( "received message: " + result ); // just log for tracing
return result.getBytes(StandardCharsets.UTF_8); // return the byte[] of the message with the needed Charset.
}
}
}
catch ( Exception e )
{
log.warning( e.getMessage() );
}
Related
I'm using a RC4 stream cipher to encrypt/decrypt data sent through a Java UDP client-server program. My code works as intended on the host program and displays the correct plaintext and ciphertext, but when the data is sent over to the client via UDP, the ciphertext in particular get a super long ciphertext appended to it.
The client is still able to decrypt it properly, I just don't understand where the random appended ciphertext is coming from.
Host program:
public class Host {
private static final String ENCRYPTION_ALGORITHM = "ARCFOUR"; // or "RC4"
public static void main(String[] args) throws Exception {
//Use Java's built-in DatagramSocket and DatagramPacket to implement UDP
DatagramSocket socket = new DatagramSocket(1500); //Create a socket to listen at port 1500
byte[] buf = new byte[65535]; //Byte array to wrap
//Initialize P, G, H(PW), A variables
BigInteger P = null;
BigInteger G = null;
String hashedPW = null; //Hashed PW using SHA-1
BigInteger A = new BigInteger(10, new Random()); //Random number selected by Alice, maximum limit of 1000
BigInteger aliceKey = null;
//Read in Diffie-Hellman parameters from param.txt
File file = new File("param.txt");
Scanner scan = new Scanner(file);
//Loop through the entire file
while(scan.hasNextLine()) {
int counter = 0;
String delimiter = ","; //Content in the file is separated using a comma
String[] tokenValue = scan.nextLine().split(delimiter);
for (String token : tokenValue) {
switch (counter++) {
case 0: //Diffie-Hellman's P
P = new BigInteger(token);
break;
case 1: //Diffie-Hellman's G
G = new BigInteger(token);
break;
case 2: //Password hashed using SHA-1
hashedPW = token;
break;
}
}
}
scan.close(); //Close scanner to prevent memory leaks
aliceKey = G.modPow(A, P); //Calculate g^a mod p to obtain Alice's public key
byte[] passwordBytes = hashedPW.getBytes();
//Setting up RC4 stream cipher
SecretKey secretKey = new SecretKeySpec(passwordBytes, 0 , passwordBytes.length, "RC4"); //Generate secret key using common password
Cipher rc4 = Cipher.getInstance(ENCRYPTION_ALGORITHM);
System.out.println("Parameters successfully read. Listening on port 1500...");
//While-loop to keep host running until terminated
while (true) {
DatagramPacket message = new DatagramPacket(buf, buf.length); //Create a packet to receive message
socket.receive(message); //Receive the message from Bob
//If Alice receives a packet with the message "Bob"
if(new String(message.getData(),0,message.getLength()).equals("Bob")) {
System.out.println("Bob has sent a connection request.");
String msgToBob = hashedPW + "," + P + "," + G + "," + aliceKey; //H(PW), P, G, G^A mod P
message.setData(encrypt(msgToBob, secretKey, rc4)); //Encrypt data using RC4
System.out.println("Ciphertext sent: " + new String(message.getData(),0,message.getLength()));
System.out.println("Decrypted text: " + decrypt(secretKey, rc4, message.getData()));
socket.send(message);
}
}
}
Client program:
public class Client {
private static final String ENCRYPTION_ALGORITHM = "ARCFOUR"; // or "RC4"
public static void main(String[] args) throws Exception {
//Use Java's built-in DatagramSocket and DatagramPacket to implement UDP
DatagramSocket socket = new DatagramSocket(); //Create socket object to send data
byte[] buffer = new byte[65535];
socket.setSoTimeout(5000); //Throw an exception if no data received within 5000ms
//Create scanner to grab user input
Scanner input = new Scanner(System.in);
System.out.print("Please enter the common password: ");
String commonPW = input.nextLine(); //Storing the password
commonPW = encryptThisString(commonPW); //Hash using SHA-1
byte[] passwordBytes = commonPW.getBytes(); //Convert password to byte-array
//Setting up RC4 stream cipher
SecretKey secretKey = new SecretKeySpec(passwordBytes, 0 , passwordBytes.length, "RC4"); //Generate secret key using common password
Cipher rc4 = Cipher.getInstance(ENCRYPTION_ALGORITHM);
System.out.print("Enter a message to send to Alice: ");
String bobInput = input.nextLine();
//Create packet containing message
DatagramPacket message = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 1500);
message.setData(bobInput.getBytes());
socket.send(message); //Send message to host
//Create separate packet to receive response (so that its length is big enough to accept)
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
System.out.println("Received from Alice: " + new String(response.getData(),0,response.getLength()));
System.out.println("Decrypted text: " + decrypt(secretKey, rc4, response.getData()));
socket.close();
}
And here's the same methods in both programs used to encrypt/decrypt data:
private static byte[] encrypt(String plaintext, SecretKey secretKey, Cipher rc4) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
rc4.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] plaintextBytes = plaintext.getBytes();
byte[] ciphertextBytes = rc4.doFinal(plaintextBytes);
//System.out.println("RC4 ciphertext base64 encoded: " + Base64.encodeBase64String(ciphertextBytes));
return ciphertextBytes;
}
private static String decrypt(SecretKey secretKey, Cipher rc4, byte[] ciphertextBytes) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
rc4.init(Cipher.DECRYPT_MODE, secretKey, rc4.getParameters());
byte[] byteDecryptedText = rc4.doFinal(ciphertextBytes);
String plaintextBack = new String(byteDecryptedText);
return plaintextBack;
}
The console output for host:
Parameters successfully read. Listening on port 1500...
Bob has sent a connection request.
q?Md|-A????±?h??♥?a????h¶^O eÆá<±?ÿ.♂/?9§}5?aaJj??fë???7óIp§T▬??ñk??lümµÅ⌂»??=L?rúk?§}x☻?.☻j:A·æu?8ë∟2äq*k∟♥?C?$??VZIù?!0|?á=I?X{♥²"‼°▲|c??2²ht??²☻P=?T?"?,9?ƒZ▼?X??M=d uöåä$M☼ñ?"♂♀ö«2&??SC?î?Å?|?#?B??⌂b9?♀??T?lƃî D^í?àêoO3{N3♦^L²¼?=ë??-?|?O{???B?♣ #Æ??½.ìV:ó?±]Ü4▲?|rA£jEGJé??♠?$K"'=«??D»m←ÿ4?J↕¥§y¶[£↨?U¬y-?ÿpëñù«←x→↨[²äueN???↨}☻zƒy??si??z?U[q??Q
?+?÷¡,7Ü?S{6?l???²??↨?%?+üá???
'½?J??«?¶?T.±#=Q!ó??>½ëY2?P☻a♂**?iLO???☺⌂♫?ñ=N?ö?k$4??äîóí←?si?↓ìÜg∟Z6↕?µáù½Rû▲b?9µ,???g?6ù?→nv?ûyµö?M¿U♥â?
e[?V?Zô$¿?¢ôq♥j????G??|?~0ÇGZ?z♥68&MoK??v·$<?âZ^??Ys??[g?? ½å\▬ß¿?·↔!N???.?'?AD?Vg?ën¢-6ô ???0,ö???}lä??Y?D?Xñ¬?º??²☺r¥ï??1?#pq?►p?▬??FMÜ-m>ßñè,?¡r??µ±#?C?¶£?¿→?oi O??♥óeòM£?N ë_?▲èv¡ï?Ü(?öW♥w²ù]q???e♠à♠íô?í^??QM?^?5éÑ??V(??? V?>è?à%?D-r∟Ü1??
N↑??·*?A?tTßæi?[??ú¬c¢ƒl??↓▲ÿie→?♠tL¡??'Ñe÷∟ ƒí?♠↑4 Ä?R;}?:'¡!n6◄▲
☻'??r?I???↨¬z?→XÄ??☼Ä{ñ:â⌂$ê{????àß?FRí???☻ª3?#9‼/¿?$/ï?{ç
öûu½Rz?▼?ô,??◄K[P∟►§PS??))?â?d▲í♥?9??Ü?¡? ««+?☼☺?<<°n¼?♂%óî↔úög
Decrypted text:
62a91401ef53536f5e4a282ca75ce2505b7f8dfe,133369106234410027239548844977121529173266794839390492022055432118963330212454946189658890281117740419231366102782626716256746218028068963594259491015958826219687167085932845323487318056081767660358673429760060452507829995471137991271021787608959982667244524929925606086596447565032707095625628293300812984091,15635507126291796032175381295261956049808038047523713881770866167494167302066120851790523759612392465402233123769308400911864440257625348397936936978922581645934310469147780992255584968935730234568508327975497520199946653504137607154138430285573487119797346741445139288140860073660395495603540644148828628224,96950246366083756365146382678616471348261490848687079335489625506702434220187716384031671233394087317377823909861019537627642960196032766557467991541000545780675424518198042877768900211198791646583260247888450303207379340549434158094990174523043323964083031376798844776809887666868545542060025549549427788304
Output for Client is similar except for the decrypted plaintext:
Please enter the common password: Popcorn
Enter a message to send to Alice: Bob
q?Md|-A????±?h??♥?a????h¶^O eÆá<±?ÿ.♂/?9§}5?aaJj??fë???7óIp§T▬??ñk??lümµÅ⌂»??=L?rúk?§}x☻?.☻j:A·æu?8ë∟2äq*k∟♥?C?$??VZIù?!0|?á=I?X{♥²"‼°▲|c??2²ht??²☻P=?T?"?,9?ƒZ▼?X??M=d uöåä$M☼ñ?"♂♀ö«2&??SC?î?Å?|?#?B??⌂b9?♀??T?lƃî D^í?àêoO3{N3♦^L²¼?=ë??-?|?O{???B?♣ #Æ??½.ìV:ó?±]Ü4▲?|rA£jEGJé??♠?$K"'=«??D»m←ÿ4?J↕¥§y¶[£↨?U¬y-?ÿpëñù«←x→↨[²äueN???↨}☻zƒy??si??z?U[q??Q
?+?÷¡,7Ü?S{6?l???²??↨?%?+üá???
'½?J??«?¶?T.±#=Q!ó??>½ëY2?P☻a♂**?iLO???☺⌂♫?ñ=N?ö?k$4??äîóí←?si?↓ìÜg∟Z6↕?µáù½Rû▲b?9µ,???g?6ù?→nv?ûyµö?M¿U♥â?
e[?V?Zô$¿?¢ôq♥j????G??|?~0ÇGZ?z♥68&MoK??v·$<?âZ^??Ys??[g?? ½å\▬ß¿?·↔!N???.?'?AD?Vg?ën¢-6ô ???0,ö???}lä??Y?D?Xñ¬?º??²☺r¥ï??1?#pq?►p?▬??FMÜ-m>ßñè,?¡r??µ±#?C?¶£?¿→?oi O??♥óeòM£?N ë_?▲èv¡ï?Ü(?öW♥w²ù]q???e♠à♠íô?í^??QM?^?5éÑ??V(??? V?>è?à%?D-r∟Ü1??
N↑??·*?A?tTßæi?[??ú¬c¢ƒl??↓▲ÿie→?♠tL¡??'Ñe÷∟ ƒí?♠↑4 Ä?R;}?:'¡!n6◄▲
☻'??r?I???↨¬z?→XÄ??☼Ä{ñ:â⌂$ê{????àß?FRí???☻ª3?#9‼/¿?$/ï?{ç
öûu½Rz?▼?ô,??◄K[P∟►§PS??))?â?d▲í♥?9??Ü?¡? ««+?☼☺?<<°n¼?♂%óî↔úög
Decrypted text:
62a91401ef53536f5e4a282ca75ce2505b7f8dfe,133369106234410027239548844977121529173266794839390492022055432118963330212454946189658890281117740419231366102782626716256746218028068963594259491015958826219687167085932845323487318056081767660358673429760060452507829995471137991271021787608959982667244524929925606086596447565032707095625628293300812984091,15635507126291796032175381295261956049808038047523713881770866167494167302066120851790523759612392465402233123769308400911864440257625348397936936978922581645934310469147780992255584968935730234568508327975497520199946653504137607154138430285573487119797346741445139288140860073660395495603540644148828628224,96950246366083756365146382678616471348261490848687079335489625506702434220187716384031671233394087317377823909861019537627642960196032766557467991541000545780675424518198042877768900211198791646583260247888450303207379340549434158094990174523043323964083031376798844776809887666868545542060025549549427788304?úmB½Ä????←ê???►\d⌂h♦4LM♣☼»??*Ñ?ì?çtº???ì?.◄☺????xK♥??Ä4öó↑↨
4?á☼mëQ«a
The actual output is much longer for the client program, I didn't copy the entire appended ciphertext. Not sure if it's relevant, but the console makes some Windows notification/error noise when it runs as well, although it doesn't actually give any compilation errors. I'm running my program using command prompt.
I don't think the issue lies with the decryption as I tested with some text on both the host and client programs and I managed to get the same decrypted plaintext just fine. Only when I send the data over UDP it causes this issue it seems.
The text infront of the original ciphertext such as "Ciphertext sent: " gets omitted in the output as well.
What am I missing?
I was trying to decrypt the entire packet buffer instead of that fraction of it that contains the actual message, which resulted in the large wall of text after the actual decrypted message.
Altering the decrypt function used to instead take in the appropriate packet size fixed the issue.
I have to send the AES encrypted json as content to web server. But after decryption, the content has extra trash symbols appeared at the beggining of the line.
My test method creates the object that is serialized and being send:
[TestMethod]
public void SendModeChangeWorksAsExpected()
{
var snpashot2Send = new ModeChangedReport
{
ControlWorkMode = ModeEnumeration.Stopped,
//Controls
ControlDate = DateTime.Now,
IsSent = false,
SentTime = null,
ReportType = ReportType.ModeChanged,
Line = new Line
{
AgencyId = "a799eb4f-86da-4af1-a221-9ed8b741b5ce"
}
};
//Создаём шифрованное значение
var encryptedString = _agencyReportEncriptingTranslator.ConvertModeChange2CypheredString(snpashot2Send);
//Отправляем в Агентство и получаем результат
var value = _agencyClient.SendModeChangeReport(encryptedString);
}
Here are the serialization and encrypt methods:
public string ConvertModeChange2CypheredString(ModeChangedReport report)
{
if (report == null) throw new ArgumentNullException(nameof(report));
//obj to json
var json = new ModeChangedReportJson
{
LineId = report.Line.AgencyId,
Mode = CreateModeFromIktToUzbekistan(report.ControlWorkMode),
ActionDate = ConvertDateToAgencyString(report.ControlDate)
};
//Serialization
var retString = _agencyJsonSerializer.SerializeReport2Json(json);
//Шифруем сериализованный json
var cypheredValue = _encryptionService.EncryptString(retString);
return cypheredValue;
}
Encrypt method:
public string EncryptString(string plaintext)
{
var plainTextBytes = Encoding.UTF8.GetBytes(plaintext);
var cypheredTextBytes = Encrypt(plainTextBytes);
var converted2Base64Value = Convert.ToBase64String(cypheredTextBytes);
return converted2Base64Value;
}
private byte[] Encrypt(byte[] bytes)
{
#region Args Validation
if (bytes == null || bytes.Length < 1)
{
throw new ArgumentException("Invalid bytes to encrypt");
}
if (_key == null || _key.Length < 1)
{
throw new InvalidOperationException("Invalid encryption key");
}
#endregion
byte[] encrypted;
try
{
using (AesManaged aes = new AesManaged())
{
aes.Key = _key;
aes.IV = _iv;
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.CBC;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, _iv);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(aes.IV, 0, aes.IV.Length);
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
}
encrypted = ms.ToArray();
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return encrypted;
}
Http client send method:
public bool SendModeChangeReport(string cypheredValue)
{
var token = GetAccessToken();
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AuthorizationToken);
client.DefaultRequestHeaders.Add("DEVICE_ID", _agencyAppSettings.DeviceId);
var content2Post = new StringContent(cypheredValue, Encoding.UTF8, "application/json");
using (var response = client.PostAsync(_agencyAppSettings.SendModeChangedReportUrl, content2Post).Result)
{
string tokenResponse = null;
try
{
tokenResponse = response.Content.ReadAsStringAsync().Result;
response.EnsureSuccessStatusCode();
return true;
}
catch (Exception ex)
{
_eventLogManager.LogError("При попытке отправить отчёт о смене режима, произошла ошибка: "
+ $"Код: {response.StatusCode}. Контент: {tokenResponse}. Ошибка: {ex.Message}.");
return false;
}
}
}
}
After decryption on receiving server, the string grows with extra trash characters at the beginning, like G���h R��EQ�Z {"lineid":"a799eb4f-86da-4af1-a221-9ed8b741b5ce"...
The decrypt method of the server (Java):
I think that the problem is the padding difference: PKCS7 on my side, and PKCS5 on server.
How can I solve this problem with the extra chars appear on server side?
Those aren't trash characters, they're the Unicode Replacement Character returned when bytes are decoded into text using the wrong character set.
The very fact you got readable text means decrypting succeeded. It's decoding the bytes into text that failed.
The bug is in the Java code. It's using the String(byte[]) which, according to the docs:
Constructs a new String by decoding the specified array of bytes using the platform's default charset.
That's obviously not UTF8. The String(byte[] bytes,Charset charset) or String(byte[] bytes,String charsetName) constructors should be used instead, passing the correct character set, eg :
byte[] decryptedBytes = cipher.doFinal(....);
return new String(decryptedBytes, StandardCharsets.UTF_8);
The hacky alternative is to change the remote server's default character set to UTF8.
I am trying to decrypt chromes encrypted field, but i get the following exception :-
Exception in thread "main" java.lang.AbstractMethodError: com.sun.jna.Structure.getFieldOrder()Ljava/util/List;
at com.sun.jna.Structure.fieldOrder(Structure.java:868)
at com.sun.jna.Structure.getFields(Structure.java:894)
at com.sun.jna.Structure.deriveLayout(Structure.java:1042)
at com.sun.jna.Structure.calculateSize(Structure.java:966)
at com.sun.jna.Structure.calculateSize(Structure.java:933)
at com.sun.jna.Structure.allocateMemory(Structure.java:360)
at com.sun.jna.Structure.<init>(Structure.java:184)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.sun.jna.Structure.<init>(Structure.java:159)
at com.sun.jna.Structure.<init>(Structure.java:151)
at com.sun.jna.platform.win32.WinCrypt$DATA_BLOB.<init>(WinCrypt.java:42)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:121)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:103)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:90)
at JPasswordManager.ChromeManager.main(ChromeManager.java:8)
Here is a snippet from my chrome class (Edit here is a sample code note - password field can be some other encrypted field i just quickly set it to that...):-
public static void main(String[] args)
{
try
{
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:\\Users\\Standard User\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data");
resultSet = statement.executeQuery("SELECT username_value, password_value FROM logins"); // some encrypted field
while (resultSet.next())
{
byte[] encryptedData = resultSet.getBytes(1);
byte[] decryptedData = Crypt32Util.cryptUnprotectData(encryptedData); // exception over here
StringBuilder decryptedString = new StringBuilder();
for (byte b : decryptedData)
{
decryptedString .append((char) b);
}
System.out.println("decrypted = [" + decryptedString + "]");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
i have also tried converting to hexString and then decrypting, that too did not work in case if you are intrested in knowing how i had converted to hex then here is a method that i coded
public static String ToHexString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
for (byte b : bytes)
{
formatter.format("%02x", b);
}
return sb.toString();
}
i used to pass encryptedData variable through this method and then try to cryptUnprotect the data but still it did not work..
sample.log contains
FLTR TID: 0000003756 RPC ID: 0000108159 Queue: Admin Client-RPC: 390626 USER: **[B#4783165b** Overlay-Group: 1
I need it to be like this
FLTR TID: 0000003756 RPC ID: 0000108159 Queue: Admin Client-RPC: 390626 USER: "DECRYPTED VALUE" Overlay-Group: 1
Use secret key as
String key = "ThisIsASecretKey";
This is what i have tried please edit wherever i wrote wrong code..
public class Decrypt {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("sample.log"));
String newStr = null;
String value = "";
while ((newStr = br.readLine()) != null) {
String next = null;
if (newStr.contains("FLTR")) {
next = newStr.substring(97, 135); // this gets string **[B#4783165b**
String collect = CallToDecrypt(next, value);
system.out.println(collect);
}
}
pt.close();
br.close();
}
private static String CallToDecrypt(String next, String value) {
String key = "ThisIsASecretKey";
byte[] raw = key.getBytes(Charset.forName("US-ASCII"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
byte[] original = cipher.doFinal();
return new String(original, Charset.forName("US-ASCII"));
}
}
Thanks to each one of you
You are tying to decrypt nothing right now: the String next is never used in the CallToDecrypt routine.
You will have to do something like
byte[] original = cipher.doFinal(next.getBytes());
I want to encrypt data in a midlet which to be sent to a servlet. I could encrypt data in midlet . I used bouncycastle. It worked perfectly(I could encrypt and decrypt well). Then I send the encrypted data to servlet. For just testing I simply used the same code(at decrypting which I used in midlet) in servlet to decrypt. But now the problem is, the data is not recieved as the midlet sends.Encrypted data has been changed. Here is sample out put which I got. this is the out put after encrypting in midlet. ø☬˕T«üwÈÉÜA?.bH¾eenter code here but when I got this from servlet thought inputstream. printed result is: øâ
˜¬Ë•T«üwÈÉÜAÂ�.bH¾e also has an exception
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher This is how I send data to server from midlet:
String serverResponse = "not send to server";
HttpConnection connection = null;
InputStream inputstream = null;
try {
connection = (HttpConnection) Connector.open(url);
connection.setRequestProperty("User-Agent", "Profile/MIDP- 1.0,Configuration/CLDC-1.0");
connection.setRequestMethod(HttpConnection.POST);
DataOutputStream os = (DataOutputStream) connection.openDataOutputStream();
System.out.println("Writing message is: " + msg);
os.writeUTF(msg);
os.flush();
os.close();
and in the servlet here is how I got: inside processRequest method -------------------------------------------------------------
response.setContentType("text/plain");
ServletInputStream sin = request.getInputStream();
String str = "";
while ((i = sin.read()) != -1) {
ch = (char) i;
str = str + ch;
}
str.trim();
System.out.println("Received Stream From MIDlet Encript data=" + str);
here is how I encrypt data using bouncycastle DES algorythm
public byte[] encrypt(String textToEnrypt, String keyString) {
Cipher cipher = null;
try {
cipher = Cipher.getInstance("DES");
} catch (Exception ex) {
System.out.println(ex.toString());
// return;
}
byte[] keyData = keyString.getBytes();
SecretKeySpec key = new SecretKeySpec(keyData, 0, keyData.length, "DES");
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (Exception ex) {
System.out.println(ex.toString());
// return;
}
int cypheredBytes = 0;
byte[] inputBytes = null;
try {
inputBytes = textToEnrypt.getBytes("UTF-8");
inputBytes = textToEnrypt.getBytes();
} catch (Exception ex) {
System.out.println(ex.toString());
//return;
}
byte[] outputBytes = new byte[100];
try {
cypheredBytes = cipher.doFinal(inputBytes, 0, inputBytes.length,
outputBytes, 0);
} catch (Exception ex) {
System.out.println(ex.toString());
//return;
}
/*
String str = new String(outputBytes, 0, cypheredBytes);
buffer = str;
System.out.println("Encrypted string = " + str);
* */
newResponse = new byte[cypheredBytes];
for (int i = 0; i < cypheredBytes; i++) {
newResponse[i] = outputBytes[i];
}
buffer=new String(newResponse);
System.out.println("Encripted text is:"+buffer);
return newResponse;
}
public void decrypt(String textToDecrypt, String keyString) {
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
} catch (Exception ex) {
System.out.println(ex.toString());
return;
}
byte[] keyData = keyString.getBytes();
SecretKeySpec key = new SecretKeySpec(keyData, 0, keyData.length, "DES");
try {
cipher.init(Cipher.DECRYPT_MODE, key);
} catch (Exception ex) {
System.out.println("2. " + ex.toString());
return;
}
int cypheredBytes = 0;
byte[] inputBytes;
try {
inputBytes =textToDecrypt.getBytes("UTF-8");
inputBytes = textToDecrypt.getBytes();
} catch (Exception ex) {
System.out.println("3. " + ex.toString());
return;
}
byte[] outputBytes = new byte[100];
try {
cypheredBytes = cipher.doFinal(inputBytes, 0, inputBytes.length,
outputBytes, 0);
} catch (Exception ex) {
System.out.println("4. " + ex.toString());
return;
}
String str = new String(outputBytes, 0, cypheredBytes);
System.out.println("Decrypted string = " + str);
}
I am new for these things. I got these codes from in this site as well. Please let me know how to get data in servelet as the midlet sends.(Without changing data.. ) if you see some error in my code or the way try to get.. pleas let me know with code sample. or else if there is an working sample code anywhere else to send data from midlet to servlet, let me know
Thank you
This is at least one possible culprit:
while ((i = sin.read()) != -1) {
ch = (char) i;
str = str + ch;
}
Why are you trying to turn opaque binary data (not text data) into a string? You're then calling String.getBytes() elsewhere to get binary data, without even specifying the encoding. Don't do this.
If you absolutely have to represent opaque binary data as text, use Base64. However,
I see no reason for using text to transfer the data in the first place - just transmit it in binary to start with.
Additionally, to convert the text to binary data before encryption (near the start of encrypt), you should specify the encoding (UTF-8 is probably a good bet). Use the same encoding after you've decrypted the binary data, and want to convert the result back into a string.
Your error message says: "javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher". You need to specify the same padding at both ends, encryption and decryption. A common padding is PKCS#5, which should be available at both ends. Don't rely on defaults, but specify the padding explicitly. Different systems may have different defaults.
John's advice on not mixing text and bytes is excellent.