[英]C# to Java TripleDES , different results
我正在尝试将此C#加密算法转换为Java; 但是,我一直在检索略有不同的加密结果(尚未尝试解密)。 指出我无法更改C#代码也可能很重要。
但是当我在字符串“test”中调用C#中的加密函数时,它将返回nmj8MjjO52y928Syqf0J+g==
但是在Java中它将返回C6xyQjJCqVo=
C#
private static String key = "012345678901234567890123";
public static string encrypt(String stringToEncrypt)
{
TripleDES des = CreateDES(key);
ICryptoTransform ct = des.CreateEncryptor();
byte[] input = Encoding.Unicode.GetBytes(stringToEncrypt);
byte[] output = ct.TransformFinalBlock(input, 0, input.Length);
//return output;
return Convert.ToBase64String(output);
}
public static String decrypt(string encryptedString)
{
byte[] input = Convert.FromBase64String(encryptedString);
TripleDES des = CreateDES(key);
ICryptoTransform ct = des.CreateDecryptor();
byte[] output = ct.TransformFinalBlock(input, 0, input.Length);
return Encoding.Unicode.GetString(output);
}
public static TripleDES CreateDES(string key)
{
MD5 md5 = new MD5CryptoServiceProvider();
TripleDES des = new TripleDESCryptoServiceProvider();
des.Key = md5.ComputeHash(Encoding.Unicode.GetBytes(key));
des.IV = new byte[des.BlockSize / 8];
return des;
}
我尝试转换为Java
private static String key = "012345678901234567890123";
public static void main(String[] args) throws Exception {
String text = "test";
String codedtext = encrypt(text);
//String decodedtext = decrypt(codedtext);
System.out.println(new String(codedtext));
//System.out.println(decodedtext);
}
public static String encrypt(String message) throws Exception {
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(key.getBytes("unicode"));
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
//for (int j = 0, k = 16; j < 8;) {
// keyBytes[k++] = keyBytes[j++];
//}
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] plainTextBytes = message.getBytes();
byte[] cipherText = cipher.doFinal(plainTextBytes);
String output = Base64.encode(cipherText);
return output;
}
public static String decrypt(String message) throws Exception {
byte[] messageBytes = Base64.decode(message);
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(key.getBytes());
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] plainText = decipher.doFinal(messageBytes);
return new String(plainText);
}
有谁看到我在监督什么?
你错过了两件事。 您在c#端使用16长度密钥,因为它没有像Java版本那样填充。 默认情况下,如果密钥长度为16个字节,则将使用密钥的前8个字节填充。
要在Java端进行匹配,您必须取消注释将该填充添加到键的那一行:
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey secretKey = new SecretKeySpec(keyBytes, 0, 24, "DESede");
此外,在Java方面,有一个建议,以确保使用UTF-LE的文本。 确保将它用于一切。 所以线条:
byte[] digestOfPassword = md.digest(key.getBytes("UTF-16LE"));
byte[] plainTextBytes = clearText.getBytes("UTF-16LE");
一般来说,我会确保设置所有三元组对象的c#参数,而不是依赖于默认值。
以下是c#和java中匹配的两个版本
Java的
String key = "012345678901234567890123";
String clearText = "test";
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(key.getBytes("UTF-16LE"));
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
String byteText = Arrays.toString(keyBytes);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey secretKey = new SecretKeySpec(keyBytes, 0, 24, "DESede");
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] plainTextBytes = clearText.getBytes("UTF-16LE");
byte[] cipherText = cipher.doFinal(plainTextBytes);
String output = Base64.encode(cipherText);
C#
string clearText = "test";
string key = "012345678901234567890123";
string encryptedText = "";
MD5 md5 = new MD5CryptoServiceProvider();
TripleDES des = new TripleDESCryptoServiceProvider();
des.KeySize = 128;
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.PKCS7;
byte[] md5Bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(key));
byte[] ivBytes = new byte[8];
des.Key = md5Bytes;
des.IV = ivBytes;
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
ICryptoTransform ct = des.CreateEncryptor();
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
encryptedText = Convert.ToBase64String(ms.ToArray());
}
编辑:现在两个版本都返回测试用例结果“nmj8MjjO52y928Syqf0J + g ==”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.