安卓 Rfc2898DeriveBytes for java?
我的后端服务器基于。网 在服务器上使用Rfc2898DeriveBytes加密
这是密码。网
public static string Encrypt(string clearText)
{
string EncryptionKey = "abc123";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
我正在用JAVA编写客户机。这是密码
try {
String encryptKey = "abc123";
byte[] salt = new byte[]{0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(encryptKey.toCharArray(), salt, 1024, 128);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES");
System.out.println("Key:" + Base64.encodeToString(secret.getEncoded(), Base64.DEFAULT));
String cleartext = "12345";
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(cleartext.getBytes("UTF-8"));
System.out.println("IV:" + Base64.encodeToString(iv, Base64.DEFAULT));
System.out.println("Cipher text:" + Base64.encodeToString(ciphertext, Base64.DEFAULT));;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
我在java中没有得到与的相同的结果。网
服务器上12345
的加密值为dAQWIrbtHv/eDbu+4oJD0g==
当我得到tcvGLK5r99jt6PFLALpRfQ==
我需要申请什么样的修正
# 1 楼答案
Rfc2898DeriveBytes
的默认迭代计数是1000,而不是1024(每the source)我不知道
PBEKeySpec
的keyLength
值是字节还是位,但在Java中是128位,在C#中是256位(32字节)事实上,你要求的是384位C#。因为前256个密码变成了你的密钥,接下来128个密码变成了你的IV(你似乎让它在Java中随机生成)
因此,您可能需要请求384位,调用^{,将答案拆分为32字节的密钥和16字节的IV,然后从那里开始
# 2 楼答案
我也通过一些调整解决了这个问题。Net代码。 Android代码如下
只需按以下方式拨打电话
对于使用java的人,可以使用java包中的Base64。util 替换加密方法中的
在decrypt方法中,替换为