Reputation: 53
I am trying to replicate this Java code in C#.
BASE64Decoder dec = new BASE64Decoder();
byte[] salt = null;
try {
salt = dec.decodeBuffer(saltStr);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Security.insertProviderAt(new BouncyCastleProvider(), 1);
String alg = "PBEWITHSHA256AND256BITAES-CBC-BC";
int derivedKeyLength = 256;
int iterations = 20000;
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations,
derivedKeyLength);
try {
SecretKeyFactory f = SecretKeyFactory.getInstance(alg);
byte[] result = f.generateSecret(spec).getEncoded();
BASE64Encoder endecoder = new BASE64Encoder();
System.out.println(endecoder.encode(result));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This is what I have so far, but it's failing. I am new to the Crypto world (so there may be an easier way to do this that I don't know) so any help would be appreciated. Thanks!
var iterations = 20000;
PbeParametersGenerator pGen = new Pkcs12ParametersGenerator(new Sha256Digest());
pGen.Init(Encoding.ASCII.GetBytes(password), Convert.FromBase64String(salt), iterations);
ICipherParameters par = pGen.GenerateDerivedParameters("AES256", 256);
IBufferedCipher c = CipherUtilities.GetCipher("PBEWITHSHA256AND256BITAES-CBC-BC");
Console.WriteLine(c.AlgorithmName);
c.Init(true, par);
byte[] enc = c.DoFinal(Convert.FromBase64String(salt));
Console.WriteLine("The output is :");
Console.WriteLine(Convert.ToBase64String(enc));
The issue is that the encrypted result is not the same in the Java and C# with the same password, the same salt, and the same number of iterations.
Update:
The problem was that the Java code (not written by me, is not doing the cipher encryption) it's only generating the key parameters. This code would give the same output as the Java code.
var iterations = 20000;
var sltBytes = Convert.FromBase64String(salt);
byte[] byteSalt = Convert.FromBase64String(salt);
byte[] pwdb = PbeParametersGenerator.Pkcs12PasswordToBytes(password.ToCharArray());
PbeParametersGenerator pGen = new Pkcs12ParametersGenerator(new Sha256Digest());
pGen.Init(pwdb, Convert.FromBase64String(salt), iterations);
var par = (ParametersWithIV)pGen.GenerateDerivedParameters("AES256", 256, 128);
var kpar = (KeyParameter)par.Parameters;
byte[] by = kpar.GetKey();
Console.WriteLine(Convert.ToBase64String(by));
Upvotes: 1
Views: 1760
Reputation: 2698
I think this is your problem:
Here you specify a derived key length of 128
int derivedKeyLength = 128;
...
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations,
derivedKeyLength);
Here you specify a derived key length of 256
ICipherParameters par = pGen.GenerateDerivedParameters("AES256", 256);
Upvotes: 1
Reputation: 6181
Your call to GenerateDerivedParameters("AES256", 256)
is specifying a different key length than the derivedKeyLength
in Java.
Upvotes: 2