我正在审核一个应用程序,我们应该检查加密算法和使用的密钥的强度。从我对代码的回顾来看,我能弄清楚的是他们正在使用3DES算法,我从提到的线路中找到了" DES / ECB / NoPadding "正在使用。
然而,在搜索加密后,我发现上面提到的加密只有56位的密钥大小。参考链接如下:
但是,应用程序开发人员说他们使用Double length 3DES。有了上述数据,我们只能弄清楚3DES已被使用,无法弄清楚密钥大小。该应用程序是在JAVA开发的。
有人可以帮助我找出使用双倍长度或三倍长度3DES的方法吗?
(OR)
提供双倍长度或三倍长度的3DES实施细节?这样我们就可以弄清楚在我的情况下可以使用什么。
答案 0 :(得分:1)
如果他们只使用DES/ECB/NoPadding
的javax.crypto,那么他们没有使用3DES
,他们正在使用DES
。不仅如此,他们使用的是ECB
,绝对不推荐。当然,他们可以使用标准DES推出他们自己的“双倍长度3DES”(无论这意味着什么),但这是另一个警示标志。
P.S。如果您不得不谷歌加密,为什么还要查看代码?你不知道代码是否安全,正如这个问题所证明的那样。
答案 1 :(得分:0)
首先,我不是密码学方面的专家,所以请适当地回答这个问题。
什么是双倍长3DES?
三重DES加密涉及对一个8字节的明文块进行加密 具有双倍长度(16字节)密钥K =(K L || K R )的8字节密文块如下:
Y = DES3(K)[X] = DES(K L )[DES -1 (K R )[DES(K L )[X]]]
解密发生如下:
X = DES -1 (K L )[DES(K R )[DES -1 (K < sub> L )[Y]]]
取自 EMV 4.2: Book 2 - Security and Key Management。
以下是如何在Java中实现它:
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Test3DES {
public static void main(String[] args) throws Exception {
//byte length has to be mutiple of 8!
String plaintext = "Attack at dawn!!";
byte[] plainBytes = plaintext.getBytes("UTF-8");
byte[] encrypted = encrypt(plainBytes);
byte[] decrypted = decrypt(encrypted);
System.out.println("Original message: ");
System.out.printf("Text: %s%n", plaintext);
System.out.printf("Raw bytes: %s%n", toHexString(plainBytes));
System.out.println("---");
System.out.println("Encrypted message: ");
System.out.printf("Text: %s%n", new String(encrypted, "UTF-8"));
System.out.printf("Raw bytes: %s%n", toHexString(encrypted));
System.out.println("---");
System.out.println("Decrypted message: ");
System.out.printf("Text: %s%n", new String(decrypted, "UTF-8"));
System.out.printf("Raw bytes: %s%n", toHexString(decrypted));
}
private static String toHexString(byte[] array) {
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
private static byte[] encrypt(byte[] message) throws Exception {
Cipher encr1, decr2, encr3;
SecretKeySpec kL, kR, tmp;
kL = new SecretKeySpec(new byte[] {0, 1, 2, 3, 4, 5, 6, 7}, "DES");
kR = new SecretKeySpec(new byte[] {8, 9, 10, 11, 12, 13, 14, 15}, "DES");
encr1 = Cipher.getInstance("DES/ECB/NoPadding");
decr2 = Cipher.getInstance("DES/ECB/NoPadding");
encr3 = Cipher.getInstance("DES/ECB/NoPadding");
encr1.init(Cipher.ENCRYPT_MODE, kL);
decr2.init(Cipher.DECRYPT_MODE, kR);
encr3.init(Cipher.ENCRYPT_MODE, kL);
return encr3.doFinal( decr2.doFinal( encr1.doFinal(message) ) );
}
private static byte[] decrypt(byte[] message) throws Exception {
Cipher decr1, encr2, decr3;
SecretKeySpec kL, kR;
kL = new SecretKeySpec(
new byte[] {0, 1, 2, 3, 4, 5, 6, 7},
"DES"
);
kR = new SecretKeySpec(
new byte[] {8, 9, 10, 11, 12, 13, 14, 15},
"DES"
);
decr1 = Cipher.getInstance("DES/ECB/NoPadding");
encr2 = Cipher.getInstance("DES/ECB/NoPadding");
decr3 = Cipher.getInstance("DES/ECB/NoPadding");
decr1.init(Cipher.DECRYPT_MODE, kL);
encr2.init(Cipher.ENCRYPT_MODE, kR);
decr3.init(Cipher.DECRYPT_MODE, kL);
return decr3.doFinal( encr2.doFinal( decr1.doFinal(message) ) );
}
}
<强>输出:强>
Original message:
Text: Attack at dawn!!
Raw bytes: 41 74 74 61 63 6B 20 61 74 20 64 61 77 6E 21 21
---
Encrypted message:
Text: #�Jɚe�P�ϸ5�%t�
Raw bytes: 23 B4 4A C9 9A 65 C5 50 90 CF B8 35 9A 25 74 A2
---
Decrypted message:
Text: Attack at dawn!!
Raw bytes: 41 74 74 61 63 6B 20 61 74 20 64 61 77 6E 21 21
所以回答你的问题 - 你在代码中寻找16字节的密钥大小。在我的代码段中,密钥由kL
和kR
组成,每个密码为8个字节,共计16个。