从 C# 到 JAVA 的 3DES 加密
3DES encrypt from C# to JAVA
我在 C# 中有此代码,我需要将其迁移到 Java。
我需要使用 3DES 加密。必填项。
C#:
public void test()
{
string sKSN = "ffff1234560006800010";
string sBDK = "E08A46B616230152230DB9C8DF94C75E";
byte[] dikKSN = new byte[10];
byte[] KSN8 = new byte[8];
byte[] BDK = new byte[16];
byte[] lKey = new byte[8];
byte[] rKey = new byte[8];
string retKey = string.Empty;
string lgTxt = string.Empty;
dikKSN = this.FromHex(sKSN); // convert hex to byte array
BDK = this.FromHex(sBDK); // convert hex to byte array
KSN8 = this.CopyByte8(dikKSN); //use the first 8 values
lKey = this.TDESEncrypt(KSN8, BDK);
}
private byte[] TDESEncrypt(byte[] data, byte[] key)
{
byte[] retVal = null;
byte[] IV = new byte[16];
System.IO.MemoryStream ms = null;
System.Security.Cryptography.TripleDES tDES = System.Security.Cryptography.TripleDES.Create();
tDES.BlockSize = 64;
tDES.KeySize = 128;
tDES.Padding = System.Security.Cryptography.PaddingMode.None;
tDES.Mode = System.Security.Cryptography.CipherMode.ECB;
System.Security.Cryptography.CryptoStream csEncrypt = null;
try
{
ms = new System.IO.MemoryStream(data);
csEncrypt = new System.Security.Cryptography.CryptoStream(ms, tDES.CreateEncryptor(key, IV), System.Security.Cryptography.CryptoStreamMode.Write);
retVal = new byte[data.Length];
csEncrypt.Write(data, 0, data.Length);
retVal = ms.ToArray();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
ms.Close();
}
return retVal;
}
JAVA:
public void test() {
String sKSN = "ffff1234560006800010";
String sBDK = "E08A46B616230152230DB9C8DF94C75E";
byte[] dikKSN = new byte[10];
byte[] KSN8 = new byte[8];
byte[] BDK = new byte[16];
byte[] lKey = new byte[8];
byte[] rKey = new byte[8];
String retKey = "";
String lgTxt = "";
dikKSN = this.fromHex(sKSN); // convert hex to byte array
BDK = this.fromHex(sBDK); // convert hex to byte array
KSN8 = this.copyByte8(dikKSN); //use the first 8 values
lKey = this.tDESEncrypt(KSN8, BDK);
}
private byte[] tDESEncrypt(byte[] plainTextBytes, byte[] kb) {
byte[] cipherText = null;
try {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(kb);
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
cipherText = cipher.doFinal(plainTextBytes);
} catch (Exception ex) {
ex.printStackTrace();
}
return cipherText;
}
执行desEncrypt方法时测试:
C#
data = {255, 255, 18, 52, 86, 0, 6, 128};
key = {224, 138, 70, 182, 22, 35, 1, 82, 35, 13, 185, 200, 223, 148, 199, 94};
JAVA
plainBytes = {-1, -1, 18, 52, 86, 0, 6, -128};
kb = {-32, -118, 70, -74, 22, 35, 1, 82, 35, 13, -71, -56, -33, -108, -57, 94}
我认为我的主要问题在于 Java 一个字节介于 -128 和 127 之间,而在 C# 中,字节原语可以包含 255 数字。
数据和关键变量的值是从相同的十六进制字符串转换为字节得到的。
我需要 Java 代码 returns 与 C# 代码具有相同的值。
此时,下面的值是 returns:
Java = {99, -104, 95, 92, 59, -75, -30, -16};
C# = {171, 58, 144, 248, 46, 146, 227, 224};
两个结果之间没有任何共同点。
解决方法在这里:
3DES Decryption Error Invalid Key Length
我删除了 MessageDigest 密钥生成并使用了以下代码:
private byte[] genTwoKey3DES(byte[] key) {
byte[] keyAux;
if (key.length == 16) {
keyAux = new byte[24];
System.arraycopy(key, 0, keyAux, 0, 16);
System.arraycopy(key, 0, keyAux, 16, 8);
} else {
keyAux = key;
}
return keyAux;
}
我在 C# 中有此代码,我需要将其迁移到 Java。 我需要使用 3DES 加密。必填项。
C#:
public void test()
{
string sKSN = "ffff1234560006800010";
string sBDK = "E08A46B616230152230DB9C8DF94C75E";
byte[] dikKSN = new byte[10];
byte[] KSN8 = new byte[8];
byte[] BDK = new byte[16];
byte[] lKey = new byte[8];
byte[] rKey = new byte[8];
string retKey = string.Empty;
string lgTxt = string.Empty;
dikKSN = this.FromHex(sKSN); // convert hex to byte array
BDK = this.FromHex(sBDK); // convert hex to byte array
KSN8 = this.CopyByte8(dikKSN); //use the first 8 values
lKey = this.TDESEncrypt(KSN8, BDK);
}
private byte[] TDESEncrypt(byte[] data, byte[] key)
{
byte[] retVal = null;
byte[] IV = new byte[16];
System.IO.MemoryStream ms = null;
System.Security.Cryptography.TripleDES tDES = System.Security.Cryptography.TripleDES.Create();
tDES.BlockSize = 64;
tDES.KeySize = 128;
tDES.Padding = System.Security.Cryptography.PaddingMode.None;
tDES.Mode = System.Security.Cryptography.CipherMode.ECB;
System.Security.Cryptography.CryptoStream csEncrypt = null;
try
{
ms = new System.IO.MemoryStream(data);
csEncrypt = new System.Security.Cryptography.CryptoStream(ms, tDES.CreateEncryptor(key, IV), System.Security.Cryptography.CryptoStreamMode.Write);
retVal = new byte[data.Length];
csEncrypt.Write(data, 0, data.Length);
retVal = ms.ToArray();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
ms.Close();
}
return retVal;
}
JAVA:
public void test() {
String sKSN = "ffff1234560006800010";
String sBDK = "E08A46B616230152230DB9C8DF94C75E";
byte[] dikKSN = new byte[10];
byte[] KSN8 = new byte[8];
byte[] BDK = new byte[16];
byte[] lKey = new byte[8];
byte[] rKey = new byte[8];
String retKey = "";
String lgTxt = "";
dikKSN = this.fromHex(sKSN); // convert hex to byte array
BDK = this.fromHex(sBDK); // convert hex to byte array
KSN8 = this.copyByte8(dikKSN); //use the first 8 values
lKey = this.tDESEncrypt(KSN8, BDK);
}
private byte[] tDESEncrypt(byte[] plainTextBytes, byte[] kb) {
byte[] cipherText = null;
try {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(kb);
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
cipherText = cipher.doFinal(plainTextBytes);
} catch (Exception ex) {
ex.printStackTrace();
}
return cipherText;
}
执行desEncrypt方法时测试:
C#
data = {255, 255, 18, 52, 86, 0, 6, 128};
key = {224, 138, 70, 182, 22, 35, 1, 82, 35, 13, 185, 200, 223, 148, 199, 94};
JAVA
plainBytes = {-1, -1, 18, 52, 86, 0, 6, -128};
kb = {-32, -118, 70, -74, 22, 35, 1, 82, 35, 13, -71, -56, -33, -108, -57, 94}
我认为我的主要问题在于 Java 一个字节介于 -128 和 127 之间,而在 C# 中,字节原语可以包含 255 数字。 数据和关键变量的值是从相同的十六进制字符串转换为字节得到的。
我需要 Java 代码 returns 与 C# 代码具有相同的值。 此时,下面的值是 returns:
Java = {99, -104, 95, 92, 59, -75, -30, -16};
C# = {171, 58, 144, 248, 46, 146, 227, 224};
两个结果之间没有任何共同点。
解决方法在这里:
3DES Decryption Error Invalid Key Length
我删除了 MessageDigest 密钥生成并使用了以下代码:
private byte[] genTwoKey3DES(byte[] key) {
byte[] keyAux;
if (key.length == 16) {
keyAux = new byte[24];
System.arraycopy(key, 0, keyAux, 0, 16);
System.arraycopy(key, 0, keyAux, 16, 8);
} else {
keyAux = key;
}
return keyAux;
}