Encrypt string in ASP decrypt in Java - java

I have below ASP code to encrypt and decrypt in asp. It works fine. I want string to be encrypted in asp and decrypt it in java.
set obj=Server.CreateObject("System.Security.Cryptography.RijndaelManaged")
Set endocde = Server.CreateObject("System.Text.endocdeEncoding")
un = endocde.GetBytes_4("Test Encryption")
obj.key = endocde.GetBytes_4("SomeRandomKey")
obj.iv = endocde.GetBytes_4("SomeRandomIv")
set enc=obj.CreateEncryptor()
uncUn=enc.TransformFinalBlock((un),0,lenb(un))
eUn=endocde.GetString((uncUn))
set dec=obj.CreateDecryptor()
byted=dec.TransformFinalBlock((uncUn),0,lenb(uncUn))
sd=endocde.GetString((byted))
I tried encrypted string to be decrypted using below code in java but doesnt work. I tried sending encrypted data in UTF8/Base64 but doesnt work. Please help.
String iv = "sameIVasASP";
String key = "sameKeyasASP";
IvParameterSpec iv = new IvParameterSpec(iv.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "Rijndael");
Cipher cipher = Cipher.getInstance("Rijndael/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decode = Base64.getDecoder().decode(<encrpted string>);
System.out.println( new String(cipher.doFinal(decode)).getBytes("UTF-8"));

How to encode/decode UTF-8 string to base64 in c#:
byte[] bytes = Encoding.UTF8.GetBytes("string-to-encode");
string base64 = Convert.ToBase64String(bytes);
How to encode/decode UTF-8 string to base64 in Java
Java8 version:
byte[] decodedBytes = Base64.getDecoder().decode(base64encodedstring);
Pre-Java8 example (with Base64 class of Commons Codec):
byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
(In Java you have many option to do that (not just these), if you are using at least Java8, there is a built in class for that, for previous versions I usually use the Base64 class in Apache Commons Codec)

Related

Decrypt sound file content in NodeJS from encryption in Java

Hello guys,
I'm working on a project that need to encrypt file content in Android and upload it to a server and then decrypt it with NodeJS service.
I have looked over a few projects that based on AES in Java and NodeJS and found something that worked on Java and not on NodeJS.
Here is the code in Java:
public static String encrypt(String encodeKey, String inputFile) throws Exception {
byte[] input = getStringFromFile(inputFile).toString().getBytes("utf-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(encodeKey.getBytes("UTF-8"));
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES/ECB/PKCS5Padding");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
String data = Base64.encodeToString(cipherText, Base64.DEFAULT);
Log.d("Crypto | Length", String.valueOf(ctLength));
Log.d("Crypto | Keypass", encodeKey);
return data;
}
And the code in NodeJS:
var
decipher = crypto.createDecipher('aes-128-ecb', encryption_key),
chunks = [];
chunks.push( decipher.update( new Buffer(fullBuffer, "base64").toString("binary")) );
chunks.push( decipher.final('binary') );
var decrypted = chunks.join("");
As you can see, for each of the files i'm generating a new key-hash for salt (it's the same for decrypt and encrypt);
My problem is that when i'm trying to decrypt it i'm getting this error from NodeJS:
digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
You aren't using the Java Cipher class correctly. You need to call the doFinal method. Since you aren't doing piecemeal encryption anyway you can dispense with the pre-sizing of the ciphertext, eliminate the call to update, and simply call
byte [] cipherText = cipher.doFinal(input);

Rijndael differences between C# and Java

I need to write Java code for encrypting a string using AES (Rijndael).
There is an already working C# code that does this same encryption for the same purpose.
The C# code:
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.KeySize = 256;
rijndaelCipher.BlockSize = 256;
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password); // password is 32 bytes long
byte[] keyBytes = new byte[32];
System.Array.Copy(pwdBytes, keyBytes, 32);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = keyBytes;
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
The Java code I came up with:
byte[] sessionKey = SENDER_KEY.getBytes(StandardCharsets.UTF_8);
byte[] iv = SENDER_KEY.getBytes(StandardCharsets.UTF_8) ;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] cipheredText = cipher.doFinal(stringedXmlForSending.getBytes());
When I execute the Java code I get the exception:
java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long
Is it true that I cannot write in Java Rijndael encryption which is using 32 bytes keys?
Another difference is that padding in the C# is PKCS7 while in Java there is PKCS5. Will it still work?
The basic Java Cryptographic Extensions only provide AES implementations which is compatible with Rijndael at 128-bit block size. You should use 128-bit BlockSize so that you are compatible with most implementations which implement AES. If you do then the padding is no problem, since PKCS#5 is the same as PKCS#7 padding in AES.
It's important to note that AES is standardized which Rijndael isn't.
I struggled significantly to get this working due to the padding issue. By theory PKCS#5 from java should match PKCS#7 padding from .Net . When I looked deeper into the issue I found that there is an issue with Base64 encoder. Java has different library to encode byte into base64. By default java uses Base64 from java.util and it gives padding issue. When I used the different library to achieve this purpose I could get the desired library.
org.apache.commons.codec.binary.Base64.encodeBase64String (byte[] encryptedtext)

Java and Javascript Blowfish

I need to send some data encrypted with Blowfish from a java-based server to a client. I can successfully encrypt data but I can't decrypt it on the client side.
Here is my java code:
byte[] kd = key.getBytes("UTF-8");
SecretKeySpec ks = new SecretKeySpec(kd, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, ks);
byte[] encrypted = cipher.doFinal(text.getBytes("UTF-8"));
String str = new String(encrypted, "UTF-8");
As for js library I decided to use this one.
out = blowfish.decrypt(code, skey, {cipherMode: 1, outputType: 0})
As a result I get some strange characters. What's wrong with my code?
UPD:
This code works perfectly:
byte[] kd = key.getBytes("UTF-8");
SecretKeySpec ks = new SecretKeySpec(kd, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, ks);
byte[] encrypted = cipher.doFinal(text.getBytes("UTF-8"));
String str = new String(Base64.encodeBase64(encrypted), "UTF-8");
JS:
out = blowfish.decrypt(code, skey, {cipherMode: 0, outputType: 0})
Sending text with \u0000 bytes in it to a browser can lead to all kinds of odd problems. That's why you should encode the data BASE64, send it to the client and then decode it locally.
Another issue is new String(encrypted, "UTF-8"); since the encoded byte array will contain illegal UTF-8 sequences. Try new String(encrypted, "iso-8859-1"); instead, it's a 1:1 encoding for arbitrary bytes. But again, the 0 bytes could confuse some component in between.

AES -256 decryption

I have an encrypted email id for unsubscribing from abcde.test.com.
for ex : https://abcde.test.com/Forms/unSubscribe.jsp?n=2&rid=00028e7353d9c4eca480a579e10ef09b&eid=588876054d458e62779be9345f399252cac7346ad8c464b8ed0bdfbff3512dd96a5b4190c5d71c30c90c34ff39e544aa
This is encrypted in aes-256.where eid="encrypted message" and rid when combined with keysize,and keystr (like "6a6b663472346c38736873346569727538346234333534376635333962353666") forms the encoded key.
Now I want to decrypt this message.
can any one help me decrypting it?
Try the following using Java SE and Apache Commons. Please note that you haven't indicated the mode or padding for your cipher (just "AES"), so you might need to make some adjustments.
// decode the key string into bytes (using Apache Commons)
byte[] keyBytes = Hex.decodeHex(keystr.toCharArray());
// create a representation of the key
SecretKeySpec spec = new SecretKeySpec(keyBytes, "AES");
// turn the key spec into a usable key
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("AES");
SecretKey key = keyFactory.generateSecret(spec);
// use a cipher to decrypt the eid
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = cipher.doFinal(hex.decodeHex(eid.toCharArray())); // decode from Hex again
I don't know what type eid represents, so turning that into something concrete is up to you, but here's an example:
String eid = new String(plainText, "ASCII");

why decrypted data is different from original data which was encrypted using java?

I am using AES encryption and decryption using java. And I use Appache commons library for conversion from string to byte and vice versa. But when I decrypt data then it is different from the input data that was encrypted using same key? why is so
Here is my code:
public static void main(String[] args) throws Exception {
String key="this is key";
String message="This is just an example";
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(Base64.decodeBase64(key)));
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted= cipher.doFinal(Base64.decodeBase64(message));
String encryptedString=Base64.encodeBase64String(encrypted);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original =
cipher.doFinal(Base64.decodeBase64(encryptedString));
System.out.println(Base64.encodeBase64String(original));
}
I get the output "Thisisjustanexamplc=" where it should have been "This is just an example". what I need to change in my code. Thanks in advance
You are base-64–decoding your plain text message. You should use message.getBytes(StandardCharsets.UTF_8) (or some other encoding) to convert to bytes instead. Base-64 encode the result of the encryption operation, then base-64 decode it before decrypting. Use new String(original, StandardCharsets.UTF_8) to convert the result of the decryption operation back to text.
In other words, use a character encoding to convert between text and bytes. Use base-64 encoding and decoding to encode binary data in a text form.

Categories