【发布时间】:2016-12-10 04:51:12
【问题描述】:
我正在尝试在 Java 和 .Net 中加密字符串。但问题是两种算法都会产生不同的结果。我正在使用三重 DES 加密算法。 它应该产生相同的结果。
我的 .Net 方法:
Public Function EncryptTripleDES(ByVal sIn As String, ByVal sKey As String) As String
Dim DES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
Dim hashMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider
' scramble the key
' Compute the MD5 hash.
DES.Key = hashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(sKey))
' Set the cipher mode.
DES.Mode = System.Security.Cryptography.CipherMode.ECB
' Create the encryptor.
Dim DESEncrypt As System.Security.Cryptography.ICryptoTransform = DES.CreateEncryptor()
' Get a byte array of the string.
Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(sIn)
' Transform and return the string.
Return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length))
End Function
我的 Java 类:
public class TrippleDESEncryption {
private static final String UNICODE_FORMAT = "UTF8";
public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
private KeySpec keySpec;
private SecretKeyFactory secretKeyFactory;
private Cipher cipher;
byte[] keyAsBytes;
private String encryptionKey;
private String encryptionScheme;
SecretKey key;
public TrippleDESEncryption() throws Exception {
encryptionKey = "234342343423434234342343";
encryptionScheme = DESEDE_ENCRYPTION_SCHEME;
keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
keySpec = new DESedeKeySpec(keyAsBytes);
secretKeyFactory = SecretKeyFactory.getInstance(encryptionScheme);
cipher = Cipher.getInstance(encryptionScheme);
key = secretKeyFactory.generateSecret(keySpec);
}
/**
* Method To Encrypt The String
*/
public String encrypt(String unencryptedString) {
String encryptedString = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] encryptedText = cipher.doFinal(plainText);
BASE64Encoder base64encoder = new BASE64Encoder();
encryptedString = base64encoder.encode(encryptedText);
} catch (Exception e) {
e.printStackTrace();
}
return encryptedString;
}
}
【问题讨论】:
-
您发布了一个 java 类与一个 C# 方法,因此我们无法告诉您将正确的参数传递给 C# 方法。您正在使用 C# 中的 ASCII 和 Java 中的 UTF-8 来获取看起来错误的关键字节。我将首先检查这些 GetBytes 调用的结果。
-
现在不要使用三重 DES。 即使您使用 192 位的最大密钥大小,它也最多只能提供 112 位的安全性。如果使用较短的密钥大小,则它仅提供 56 或 57 位的安全性。 AES 会更快(处理器具有特殊的 AES-NI 指令集),并且使用 128 位的最低密钥大小甚至更安全。 3DES 的最大密文大小也有实际限制。见Security comparison of 3DES and AES。
-
切勿使用ECB mode。它是确定性的,因此在语义上不安全。您至少应该使用像CBC 或CTR 这样的随机模式。最好对您的密文进行身份验证,以免像padding oracle attack 这样的攻击是不可能的。这可以通过 GCM 或 EAX 等认证模式或encrypt-then-MAC 方案来完成。
-
一般建议:始终使用完全限定的密码字符串。
Cipher.getInstance("DESede");可能会产生不同的密码,具体取决于默认的安全提供程序。它最有可能导致"DESede/ECB/PKCS5Padding",但并非必须如此。如果它发生变化,您将失去不同 JVM 之间的兼容性。
标签: java .net vb.net encryption