AES:Java中的ECB模式加密



我实际上正在研究AES加密的ECB模式和CBC模式之间的差异。经过一番研究,我发现ECB模式存在一些缺陷,如果使用相同的密钥和内容加密,它会为明文创建相同的密文。另一方面,在CBC中,有初始化向量来克服这个问题,该问题在每次加密的运行时都会产生字节的随机性。

现在,在一些论坛上,我知道如果两个纯文本之间有相似的块,那么每次都会产生相同的密文;这将帮助黑客识别常见的密码模式。

我用一些Java代码进行了尝试,并提供了以下两个纯文本:

Jimmy Anderson.
Corrie Anderson.

现在,Anderson这个词在两者之间很常见,但当我对它进行加密并打印输出时,它产生了不同的密文。然而,加密同一段明文会产生类似的密文,这很好。但为什么它会为常见的姓氏产生不同的密码呢?

另一个问题是,如果我们在每个加密循环中使用随机密钥生成,那么即使是相同的明文,它也总是会产生不同的密码,因为密钥不同?

那么,如果CBC在这里得到满足,它需要什么呢?

有人能帮我吗?

如有任何帮助,我们将不胜感激:(。

public static String encryptwithecb ( byte[] plaintext, SecretKey key )  throws Exception
{
Cipher cipher = Cipher.getInstance( "AES/ECB/PKCS5Padding" );
SecretKeySpec keyspec = new SecretKeySpec( key.getEncoded(), "AES" );
cipher.init( Cipher.ENCRYPT_MODE,  keyspec );
byte[] cipherText = cipher.doFinal( plaintext );
return Base64.getEncoder().encodeToString( cipherText );
}
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
// Generate Key
SecretKey key = keyGenerator.generateKey();
System.out.println("");
System.out.println("");
System.out.println("***** ENCRYPT WITH ECB ****** ");
System.out.println("");
String name1 = "Jimmy Anderson";
String name2 = "Corrie Anderson..";
String ecb = encryptwithecb( name1.getBytes("UTF-8") , key);
String ecb2 = encryptwithecb( name2.getBytes("UTF-8") , key);
String ecb3 = encryptwithecb( name1.getBytes("UTF-8") , key);
System.out.println(ecb);
System.out.println(ecb2);
System.out.println(ecb3);
System.out.println("");
System.out.println("***** ENCRYPT WITH ECB ****** ");
System.out.println("");
System.out.println("");

输出

***** ENCRYPT WITH ECB ****** 
gs3y1N8jA7kwzO/c/dzwEA==
yKFC43ySA1NBAnRdvp9jEHtfcJeM7bAlmcMY63Aeupc=
gs3y1N8jA7kwzO/c/dzwEA==
***** ENCRYPT WITH ECB ******

ECB模式在任何块匹配的情况下都会产生相同的密文。AES的块为16个字节。这不仅适用于初始块,也适用于加密消息所需的任何块。在您的示例中,第一个块不同,因为名字不同。除此之外,明文被移动了一个字符。块总是从作为块边界的偏移开始,当然也是16的倍数。

是的,每次都可以生成不同的密钥。但这通常效率很低。例如,你必须在发送者和接收者之间安全地共享密钥,而IV可以包含在消息中。也许密钥存储在您不想更新的安全硬件位置。执行Diffie-Hellman密钥协议来建立密钥是相当昂贵的。

对于CBC,IV对对手来说必须是不可预测的(通常通过使其随机来解决(。许多其他模式,如计数器模式或GCM模式,只需要一个nonce,在这种情况下,您可以使用消息计数器,这通常是禁止重放攻击所必需的。

最新更新