TripleDes的加密工作在Java罚款,但不是在C#
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TripleDes的加密工作在Java罚款,但不是在C#相关的知识,希望对你有一定的参考价值。
我面临的弱密钥错误,而这样做的TripleDES encryption.Code工作在Java罚款,但在C#.NET给错误。
我在这三重DES加密工作正常,我需要转换我的Java代码在C#。我现在面临弱密钥错误conversion.Below期间Java和C#代码给出的Java代码。
1)Java代码的
public class TripleDES {
private DESedeKeySpec desKeySpec;
public TripleDES(String key) {
try {
byte[] keyBytes = { (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,
(byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,
(byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,
(byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,
(byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,
(byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02};
this.desKeySpec = new DESedeKeySpec(keyBytes);
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] encrypt(byte[] origData) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(this.desKeySpec);
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(origData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public byte[] decrypt(byte[] crypted) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(this.desKeySpec);
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding"); //DESede/CBC/PKCS5Padding
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(crypted);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws Exception {
TripleDES des = new TripleDES("");
byte[] data = { (byte)0x04, (byte)0x12, (byte)0x05, (byte)0xFF, (byte)0xFB, (byte)0xA6, (byte)0x66, (byte)0xCF};
//byte[] data = { (byte)0x04, (byte)0x12, (byte)0x15, (byte)0xAF, (byte)0xFD, (byte)0xD8, (byte)0x88, (byte)0xBB};
//-----------------Edited-----------------
String text = new BigInteger(1, data).toString(16);
System.out.println("Before encryption = " +text);
byte[] crypted = des.encrypt(data);
String text1 = new BigInteger(1, crypted).toString(16);
System.out.println("Encrypted = " +text1);
byte[] decrypted = des.decrypt(crypted);
String text2 = new BigInteger(1, decrypted).toString(16);
System.out.println("Decrypted = " +text2);
}
}
2)C#代码
static void Main(string[] args)
{
String Data = EncryptDES("041205FFFBA666CF");
}
public static string EncryptDES(string InputText)
{
byte[] key = new byte[] { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 };
byte[] clearData = System.Text.Encoding.UTF8.GetBytes(InputText);
MemoryStream ms = new MemoryStream();
TripleDES alg = TripleDES.Create();
alg.Key = key;
alg.Mode = CipherMode.ECB;
CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(clearData, 0, clearData.Length);
cs.FlushFinalBlock();
byte[] CipherBytes = ms.ToArray();
ms.Close();
cs.Close();
string EncryptedData = Convert.ToBase64String(CipherBytes);
return EncryptedData;
}
重点:02020202020202020202020202020202
数据:041205FFFBA666CF
结果:A334C92CEC163D9F
任何人都可以请编写C#代码产生的结果相同的Java。
在我开始,我想说的是,我不推荐或认可您按照这种方式迫使TripleDes的使用它认为关键是弱,不过,由于您使用它进行解密只是,这里是一个办法做到它使用反射。
首先,您必须“强制”的TripeDES
类带您要使用的弱密钥。要做到这一点,我们使用反射来绕过那就是当你尝试设置键(alg.Key = key
)进行弱密钥检查,并直接设置成员变量:
//alg.Key = key; - THIS IS REPLACED BY THE BELOW
FieldInfo keyField = alg.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance);
keyField.SetValue(alg, key);
TripleDES
的键值,将被设置到你的弱密钥(alg.Key
);
接下来你有一个小的失误,因为你忘记关闭填充:
alg.Mode = CipherMode.ECB;
alg.Padding = PaddingMode.None; // Add this, as the default padding is PKCS7
最后,将是创建解密时弱密钥进一步检查,所以我们必须再次使用反射来绕过检查和创建ICryptoTransform的:
// Comment out the below line and use the code below
// CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
ICryptoTransform Decryptor;
MethodInfo createMethod = alg.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
Decryptor = createMethod.Invoke(alg, new object[] { alg.Key, alg.Mode, alg.IV, alg.FeedbackSize, 1 }) as ICryptoTransform;
CryptoStream cs = new CryptoStream(ms, Decryptor, CryptoStreamMode.Write);
现在,该代码将运行并接受弱密钥,并执行你正在寻找解密。
但是,它不看,我认为输出是你期待什么:
?Data
"4aU3DcHkiCTEywpiewWIow=="
至少现在虽然你可以使用你想要TripleDES
哪个键。
甲3DES密钥是24字节的值,该值被分解两个三8字节值:key0
,key1
,key2
。
因为3DES是DES_ENCRYPT(KEY2,DES算法(KEY1,DES_ENCRYPT(KEY0,数据)))的任何时间key1
等于key2
或key0
算法减小到DES。这是.NET的TripleDes的警告你一下。
这里的合适的测试应占在每个字节清零(或设置,或固定)的奇偶校验比特,但手波形版本是:
SymmetricAlgorithm alg;
IEnumerable<byte> key0 = key.Take(8);
IEnumerable<byte> key1 = key.Skip(8).Take(8);
IEnumerable<byte> key2 = key.Skip(16);
if (key0.SequenceEquals(key1))
{
alg = DES.Create();
alg.Key = key2.ToArray();
}
else if (key1.SequenceEquals(key2))
{
alg = DES.Create();
alg.Key = key0.ToArray();
}
else
{
alg = TripleDES.Create();
alg.Key = key;
}
要更换你的两个内胆:
TripleDES alg = TripleDES.Create();
alg.Key = key;
以上是关于TripleDes的加密工作在Java罚款,但不是在C#的主要内容,如果未能解决你的问题,请参考以下文章
多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现
TripleDES 加密在 c# 和 PHP 中没有得到相同的结果