2017-02-01 2 views
3

私の暗号が以下のベクトルに基づいて予想される出力よりも長い理由を理解できません。私はそれが非常にきれいで明確だと思うので、私はコードを説明しません。このAES 128暗号化で何が問題になっていますか?

package mundo; 
import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 

class AESTest { 
    public static void main(String[] args) throws Exception { 
    //each array is a vector case {key, plainText, expectedCipher} 
    String[][] cases = new String[][]{{"00000000000000000000000000000000", "f34481ec3cc627bacd5dc3fb08f273e6","0336763e966d92595a567cc9ce537f5e"}, 
             {"00000000000000000000000000000000", "9798c4640bad75c7c3227db910174e72", "a9a1631bf4996954ebc093957b234589"}, 
             {"2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"}, 
             {"2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"}}; 
    for(String[] kase : cases) 
    { 
     byte[] theKey = byte2hex(kase[0]); 
     byte[] theMsg = byte2hex(kase[1]); 
     byte[] theExp = byte2hex(kase[2]); 
     Cipher cipher = Cipher.getInstance("AES"); 
     SecretKeySpec keySpec = new SecretKeySpec(theKey, "AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, keySpec); 
     byte[] cryptMsg = cipher.doFinal(theMsg); 
     System.out.println("Key  : "+hex2byte(theKey)); 
     System.out.println("Message : "+hex2byte(theMsg)); 
     System.out.println("Cipher : "+hex2byte(cryptMsg)); 
     System.out.println("Expected: "+hex2byte(theExp) + "\n"); 
    } 
    } 
    public static String hex2byte(byte[] array) { 
     return DatatypeConverter.printHexBinary(array); 
    } 
    public static byte[] byte2hex(String s) { 
     return DatatypeConverter.parseHexBinary(s); 
    } 
} 

これが出力されます。

Key  : 00000000000000000000000000000000 
Message : F34481EC3CC627BACD5DC3FB08F273E6 
Cipher : 0336763E966D92595A567CC9CE537F5E0143DB63EE66B0CDFF9F69917680151E 
Expected: 0336763E966D92595A567CC9CE537F5E 

Key  : 00000000000000000000000000000000 
Message : 9798C4640BAD75C7C3227DB910174E72 
Cipher : A9A1631BF4996954EBC093957B2345890143DB63EE66B0CDFF9F69917680151E 
Expected: A9A1631BF4996954EBC093957B234589 

Key  : 2B7E151628AED2A6ABF7158809CF4F3C 
Message : 6BC1BEE22E409F96E93D7E117393172A 
Cipher : 3AD77BB40D7A3660A89ECAF32466EF97A254BE88E037DDD9D79FB6411C3F9DF8 
Expected: 3AD77BB40D7A3660A89ECAF32466EF97 

Key  : 2B7E151628AED2A6ABF7158809CF4F3C 
Message : AE2D8A571E03AC9C9EB76FAC45AF8E51 
Cipher : F5D3D58503B9699DE785895A96FDBAAFA254BE88E037DDD9D79FB6411C3F9DF8 
Expected: F5D3D58503B9699DE785895A96FDBAAF 

なぜ暗号に予想以上です。これは参考書から取られた128ビットのAESベクトルである。

EDITは、コードに追加:

cipher.init(Cipher.DECRYPT_MODE, keySpec); 
byte[] dcrypMsg = cipher.doFinal(cryptMsg); 
System.out.println("Decrypted: " + byte2hex(dcrypMsg) + "\n"); 

解読が正しいですが、私はまだ理解できない...

Key  : 2B7E151628AED2A6ABF7158809CF4F3C 
Message : AE2D8A571E03AC9C9EB76FAC45AF8E51 
Cipher : F5D3D58503B9699DE785895A96FDBAAFA254BE88E037DDD9D79FB6411C3F9DF8 
Expected: F5D3D58503B9699DE785895A96FDBAAF 
Decrypted: AE2D8A571E03AC9C9EB76FAC45AF8E51 

答えて

4

ご入力がない、ことを確認するCipher.getInstance("AES/ECB/NoPadding"); を使用してください詰まらない 次に、すべてのテストケースについて予想される出力が得られます。 https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.htmlによれば

変換の形式のものである:

「アルゴリズム/モード/パディング」または「アルゴリズム」(後者の場合、用 プロバイダ固有のデフォルト値モードおよびパディング方式は、 が使用されます)。

指定しないと、どのようなパディングが使用されているかわかりません。私はあなたの入力データが埋め込まれていると仮定します。つまり、あなたの暗号のブロックサイズの完全なブロックがあるように、あなたの入力に何かが追加されます。あなたの入力の長さは既にブロックサイズで割り切れるので、完全なブロックが追加され、Messageの結果、予想される長さの2倍になります。

2

暗号ブロック連鎖モードとパディングアルゴリズムを指定しない場合、JDKはデフォルトを使用します。暗号仕様は、それらを指定しないに対して助言:完全に アルゴリズム、モード、およびパディングを指定する変換を使用することをお勧めします

。そうしないと、プロバイダは デフォルトを使用します。たとえば、のSunJCEプロバイダとSunPKCS11プロバイダでは、ECBを デフォルトモードに、PKCS5Paddingを多くの 対称暗号のデフォルトパディングとして使用しています。

Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); 
: - のでノーブロック連鎖 - なしパディング
http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html#trans

ご所望の出力を取得するには、電子クックブックモード(ECB)を使用する必要があります

関連する問題