5

The encryption is in java:


String salt = "DC14DBE5F917C7D03C02CD5ADB88FA41";
String password = "25623F17-0027-3B82-BB4B-B7DD60DCDC9B";

char[] passwordChars = new char[password.length()];
password.getChars(0,password.length(), passwordChars, 0);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passwordChars, salt.getBytes(), 2, 256);
SecretKey sKey = factory.generateSecret(spec);
byte[] raw = _sKey.getEncoded();

String toEncrypt = "The text to be encrypted.";

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, skey);

AlgorithmParameters params = cipher.getParameters();
byte[] initVector = params.getParameterSpec(IvParameterSpec.class).getIV();

byte[] encryptedBytes = cipher.doFinal(toEncrypt.getBytes());

While the decryption is in c#:


string hashAlgorithm = "SHA1";
int passwordIterations = 2;
int keySize = 256;

byte[] saltValueBytes = Encoding.ASCII.GetBytes( salt );
byte[] cipherTextBytes = Convert.FromBase64String( cipherText );

PasswordDeriveBytes passwordDB = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm  passwordIterations );

byte[] keyBytes = passwordDB.GetBytes( keySize / 8 );

RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform decryptor = symmetricKey.CreateDecryptor( keyBytes, initVector );

MemoryStream memoryStream = new MemoryStream( cipherTextBytes );

CryptoStream cryptoStream = new CryptoStream( memoryStream, decryptor, CryptoStreamMode.Read );

byte[] plainTextBytes = new byte[ cipherTextBytes.Length ];

int decryptedByteCount = cryptoStream.Read( plainTextBytes, 0, plainTextBytes.Length );

memoryStream.Close();
cryptoStream.Close();

string plainText = Encoding.UTF8.GetString( plainTextBytes, 0, decryptedByteCount );

The decryption failed with exception "Padding is invalid and cannot be removed."

Any idea what might be the problem?

SwDevMan81
  • 45,922
  • 20
  • 140
  • 177
Wijaya
  • 51
  • 1
  • 3

1 Answers1

5

This generally indicates that decryption has failed. I suggest you check the output of the key generation functions, to see if you are actually using the same key. I notice, for instance, that the Java code implies you are using a SHA1-based HMAC, whereas the .NET code implies you are using an unkeyed SHA1 hash to generate the key.

Alternatively, it could be a mismatch in the padding. I don't see where you are explicitly setting the PaddingMode to PKCS7 in the .NET code.

David M
  • 68,374
  • 13
  • 151
  • 181
  • Thanks for the reply. Basically, I am coding up the java side of it, and have no control over the .NET side. However, I have the source code of both sides and while debugging the .NET side, it shows the PKCS7. I guess my question would be, what should I do on the java side to match the existing .NET decryption? – Wijaya Jan 22 '10 at 23:01
  • The default `PaddingMode` in .NET is PKCS7, I've just checked. So I suspect there is a difference in the key generation. `PasswordDeriveBytes` uses the PBKDF1 algorithm, whereas your Java code uses PBKDF2. I'm not sufficiently familiar with what's available in Java, but is there a way you can use PBKDF1? – David M Jan 22 '10 at 23:06
  • Hi David. You're right, the keys did not match. Turns out BouncyCastle has a class that built just for this. org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator I found this thread very usefull: http://old.nabble.com/.NET-PasswordDeriveBytes-tt9114084.html#a9114084 It works now. Thanks for the insight. – Wijaya Jan 25 '10 at 03:08