2

我有以下三重 DES 的 C# 实现

byte[] bKey = HexToBytes("C67DDB0CE47D27FAF6F32ECA5C99E8AF");
byte[] bMsg = HexToBytes("ff00");
byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Padding = PaddingMode.Zeros;
des.Mode = CipherMode.CBC;
byte[] bK1 = new byte[8];
for (int i = 0; i < 8; i++) bK1[i] = bKey[i];
byte[] bK2 = new byte[8];
for (int i = 0; i < 8; i++) bK2[i] = bKey[i + 8];
ICryptoTransform ict1 = des.CreateEncryptor(bK1, iv);
byte[] bFt = ict1.TransformFinalBlock(bMsg, 0, bMsg.Length);
byte[] bLCb = new byte[8];
for (int i = 0; i < 8; i++) bLCb[i] = bFt[i + bFt.Length - 8];
des.Mode = CipherMode.ECB;
ICryptoTransform ict1_5 = des.CreateDecryptor(bK2, iv);
bLCb = ict1_5.TransformFinalBlock(bLCb, 0, bLCb.Length);
ICryptoTransform ict2 = des.CreateEncryptor(bK1, iv);
byte[] bMac = ict2.TransformFinalBlock(bLCb, 0, bLCb.Length);

ToHex(bMac); // outputs: 4BC0479D7889CF8E

我需要在 Java/Groovy 中产生相同的结果,我显然陷入了困境。我现在的代码如下:

byte[] bKey = Hex.decode("C67DDB0CE47D27FAF6F32ECA5C99E8AF")
byte[] bMsg = Hex.decode("ff00")

byte[] keyBytes = Arrays.copyOf(sKey.bytes, 24)
int j = 0, k = 16
while (j < 8) {
    keyBytes[k++] = keyBytes[j++]
}

SecretKey key3 = new SecretKeySpec(keyBytes, "DESede")
IvParameterSpec iv3 = new IvParameterSpec(new byte[8])
Cipher cipher3 = Cipher.getInstance("DESede/CBC/PKCS5Padding")
cipher3.init(Cipher.ENCRYPT_MODE, key3, iv3)

byte[] bMac = cipher3.doFinal(bMsg)
println new String(Hex.encode(bMac))

这一个输出:ef2c57c3fa18d0a5

Hex.decode()这是充气城堡

我还尝试通过在最后一轮使用 DES/CBC 和 EBC 在 Java 中重现相同的 C# 代码,这给了我什至不同的结果:48f63c809c38e1eb

如果有人能给我暗示我可能做错了什么,那就太好了

更新:

感谢大家的帮助!无需太多调整即可按需工作的最终代码:

Security.addProvider(new BouncyCastleProvider())
byte[] bKey = Hex.decode("C67DDB0CE47D27FAF6F32ECA5C99E8AF")
byte[] bMsg = Hex.decode("ff00")

byte[] keyBytes = Arrays.copyOf(sKey.bytes, 24)
int j = 0, k = 16
while (j < 8) {
    keyBytes[k++] = keyBytes[j++]
}

SecretKey key3 = new SecretKeySpec(keyBytes, "DESede")
IvParameterSpec iv3 = new IvParameterSpec(new byte[8])
Cipher cipher3 = Cipher.getInstance("DESede/CBC/ZeroBytePadding")
cipher3.init(Cipher.ENCRYPT_MODE, key3, iv3)

byte[] bMac = cipher3.doFinal(bMsg)
println new String(Hex.encode(bMac))
4

1 回答 1

4

您正在使用一些非标准的填充和块链接。你将无法使用DESede. 请尝试DES

import javax.crypto.*
import javax.crypto.spec.*

def key1 = new SecretKeySpec("C67DDB0CE47D27FA".decodeHex(), "DES")
def key2 = new SecretKeySpec("F6F32ECA5C99E8AF".decodeHex(), "DES")
def plaintext = ("ff00" + "000000000000").decodeHex() // manually zero pad

def c1 = Cipher.getInstance("DES/CBC/NoPadding")
c1.init(Cipher.ENCRYPT_MODE, key1, new IvParameterSpec(new byte[8]))
def cipherText1 = c1.doFinal(plaintext) 

def c2 = Cipher.getInstance("DES/CBC/NoPadding")
c2.init(Cipher.DECRYPT_MODE, key2, new IvParameterSpec(new byte[8]))
def cipherText2 = c2.doFinal(cipherText1)

def c3 = Cipher.getInstance("DES/ECB/NoPadding")
c3.init(Cipher.ENCRYPT_MODE, key1)
def cipherText3 = c3.doFinal(cipherText2)

assert cipherText3.encodeHex().toString() == "4bc0479d7889cf8e"
于 2012-07-03T16:19:45.003 回答