我需要将下面的C#代码翻译成Java,但是,我找不到任何与C#的Rfc2898DerivedBytes和Rijndael相当的Java。
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;
}
[更新]
我需要使用此函数来加密新创建的用户的密码,加密的密码也应该被包括C#在内的其他调用者正确解密。
我按照评论和答案中列出的文件进行操作,并尝试在下面编写简单的样本以便快速验证。
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);
}
}
然而,密文的长度是48,但实际上在C#中,它看起来像这种格式
总共120个字符。WHUNV5xrsfETEiCwcT0M731 + Ak1jibsWEodJSaBraP1cmmkS1TpGWqwt / 6P / a7oy8Yq30ImZPbFF + Y0JNLa3Eu2UGuazZtuhEepUIIdaDEtA2FO0JYIj2A ==
代码有问题吗?
答案 0 :(得分:5)
RFC2898是PBKDF2(基于密码的密钥派生函数)的正式名称。
这个问题似乎使用PBKDF2的SecretKeyFactory
类。
Password Verification with PBKDF2 in Java
如果你找不到任何你满意的实现,我建议你看看my question我在哪里使用了BouncyCastle的几个类(对于C#,但应该适用于Java)并创建了算法。我不得不为C#创建它,因为.NET Compact Framework没有Rfc2898DeriveBytes
。
This question也一定对你有所帮助!
您还可以找到由遇到同一问题的人完成的实施here。
同样回答你问题的第二部分,
Rijndael与AES没有多大区别。引用此webpage
即,Rijndael允许选择密钥和块大小 独立于{128,160,192,224,256}位的集合。 (和 密钥大小实际上不必匹配块大小)。然而, FIPS-197指定块大小在AES中必须始终为128位, 并且密钥大小可以是128,192或256位。
NIST选择Rijndael算法作为高级加密算法。
所以你可以使用AES algorithm in Java。