I need to translate the below C# codes into Java, however, I could not find any Java equivalent to the Rfc2898DerivedBytes and Rijndael of C#.
private static string Encrypt(string sData, string sEncryptionKey)
{
string str = null;
string str2;
try
{
Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(sEncryptionKey, 8);
Rijndael rijndael = Rijndael.Create();
rijndael.IV = bytes.GetBytes(rijndael.BlockSize / 8);
rijndael.Key = bytes.GetBytes(rijndael.KeySize / 8);
byte[] buffer = Encoding.Unicode.GetBytes(sData);
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
{
stream.Write(bytes.Salt, 0, bytes.Salt.Length);
stream2.Write(buffer, 0, buffer.Length);
stream2.Close();
str = Convert.ToBase64String(stream.ToArray());
str2 = str;
}
}
}
catch (Exception exception)
{
System.out.println(exception.getMessage());
}
return str2;
}
[Update]
I need to use this function to encrypt the password for new created user, and the encrypted password should also be correctly decrypted by other invoker including C#.
I follow the documents which list in the comments and answer, and try to write below simply sample for quickly verification.
public class testEncrypt {
public static void main(String[] args) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
char[] password = "passkey".toCharArray();
SecureRandom random = new SecureRandom();
byte[] salt = new byte[8];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec(password, salt, 1000, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("301a7fed-54e4-4ae2-9b4d-6db057f75c91".getBytes("UTF-8"));
System.out.println(ciphertext.length);
}
}
However, the length of the ciphertext is 48, but actually in C#, it looks like this format
WHUNV5xrsfETEiCwcT0M731+Ak1jibsWEodJSaBraP1cmmkS1TpGWqwt/6p/a7oy8Yq30ImZPbFF+Y0JNLa3Eu2UGuazZtuhEepUIIdaDEtA2FO0JYIj2A==
total 120 characters.
Is there something wrong with the code?
RFC2898 is the official name for PBKDF2 (Password Based Key Derivation Function).
This question seems to use the
SecretKeyFactory
class for PBKDF2.Password Verification with PBKDF2 in Java
If you cannot find any implementation that you are satisfied with, I suggest you take a look at my question where I used a few classes from BouncyCastle (for C#, but should work for Java) and created the algorithm. I had to create this for C# because there was no
Rfc2898DeriveBytes
for the .NET Compact Framework.This question should definitely help you too!
You can also find an implementation here that was done by someone who stumbled across your same problem.
Also to answer the second part of your question,
Rijndael doesn't differ much from AES. To quote this webpage
Rijndael algorithm was chosen by the NIST to be the Advanced Encryption algorithm.
So you can use the AES algorithm in Java.