2017-03-13 5 views
0

내가하려는 것은 웹 브라우저에서 SubtleCrypto.encrypt()가 제공하는 128 비트 AES-CBC 암호화를 사용하여 16 바이트 패킷의 데이터를 암호화하는 것입니다.WebCrypto를 사용하여 AES로 암호화 된 데이터 길이

내가 예상 한 바는 16 바이트의 입력에 대해 16 바이트의 암호화 된 데이터였습니다.

실제로 16 바이트 입력에 대해 32 바이트의 암호화 된 데이터가 있습니다.

특히 15 바이트 입력은 16 바이트 출력을 생성하고 16 바이트 입력은 32 바이트 출력을 생성하며 17 바이트 데이터는 32 바이트 출력을 생성합니다.

제 질문은 왜 16 바이트의 입력 데이터가 32 바이트 출력을 생성합니까? 나는 이것이> 16 바이트가 아닌> 16 바이트의 입력 데이터에서만 발생할 수 있다고 생각했을 것이다.

다음 테스트 코드를 파일로 저장하고 웹 브라우저로 엽니 다.

<html> 
<head> 
<script> 

    var myKey = window.crypto.getRandomValues(new Uint8Array(16)); 
    console.log("Raw key = " + myKey); 
    var keyObj = {}; 
    var keyFormat = "raw"; 
    var extractable = false; 
    var usages = ["encrypt", "decrypt"]; 
    window.crypto.subtle.importKey(keyFormat, myKey, "AES-CBC", extractable, usages) 
    .then(function(importedKey) { 
    keyObj = importedKey; 
    console.log("Encryption/Decryption key object = " + keyObj); 

    var vector = window.crypto.getRandomValues(new Uint8Array(16)); 

    var encryptThis15 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); 
    var encryptThis16 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]); 
    var encryptThis17 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]); 

    var decryptSuccess = function(decrypted) { 
     var decryptedData = new Uint8Array(decrypted); 
     console.log("Decrypted data = " + decryptedData.length + " bytes: " + decryptedData); 
    }; 

    var decryptFail = function(error) { 
     // Fail. 
     console.log("Failure decrypting data. Error: " + error); 
    }; 

    var encryptSuccess = function(encData) { 
     var encryptedData = new Uint8Array(encData); 
     console.log("Encrypted data = " + encryptedData.length + " bytes: " + encryptedData); 
     return encData; 
    }; 

    var encryptFail = function(error) { 
     console.log("Failure encrypting data. Error: " + error); 
    }; 

    console.log("15 byte data array as input = " + encryptThis15); 

    window.crypto.subtle.encrypt({name: "AES-CBC", iv: vector}, keyObj, encryptThis15) 
    .then(encryptSuccess) 
    .then(function(encrypted){return window.crypto.subtle.decrypt({name: "AES-CBC", iv: vector}, keyObj, encrypted);}) 
    .then(decryptSuccess) 
    .catch(decryptFail); 

    console.log("16 byte data array as input = " + encryptThis16); 

    window.crypto.subtle.encrypt({name: "AES-CBC", iv: vector}, keyObj, encryptThis16) 
    .then(encryptSuccess) 
    .then(function(encrypted){return window.crypto.subtle.decrypt({name: "AES-CBC", iv: vector}, keyObj, encrypted);}) 
    .then(decryptSuccess) 
    .catch(decryptFail); 

    console.log("17 byte data array as input = " + encryptThis17); 

    window.crypto.subtle.encrypt({name: "AES-CBC", iv: vector}, keyObj, encryptThis17) 
    .then(encryptSuccess) 
    .then(function(encrypted){return window.crypto.subtle.decrypt({name: "AES-CBC", iv: vector}, keyObj, encrypted);}) 
    .then(decryptSuccess) 
    .catch(decryptFail); 

    }) 
    .catch(function(err){ 
    console.log("Key generation error = " + err); 
    }); 

</script> 
<title>WebCrypto encrypt test</title> 
</head> 
<body> 
<p>See console log.</p> 
</body> 
</html> 
+1

[this] (http://stackoverflow.com/a/3284136/6371459)에 따르면 결과는 정확합니다. – pedrofb

답변

1

PKCS 번호 7분의 5 패딩 블록들이 완료 될 때까지 블록이 평문의 바이트 aa 바이트를 추가해야한다고 지시한다.

  • 15 바이트를 : 당신이 암호화하려는 경우 즉, 패딩 01
  • 14 바이트가된다 : 패딩은 02 02
  • 13 바이트가된다 : 패딩은 03 03 03

하면된다 이 패딩 모드를 사용하고 있으며 블록 크기와 동일한 크기 (사용자의 경우 16 바이트) 인 데이터를 암호화하면 블록에 패딩이 적용되지 않고 동일한 패딩 모드로 해독이 실패합니다. 따라서 평문 끝에 0x10의 16 바이트를 추가해야합니다.