これがCryptoJS3.1.2のバージョンです。次のことに常に注意してください(両方の言語で同じものを使用してください)。
- 動作モード(この場合はCBC)
- パディング(この場合はゼロパディング。PKCS#7パディングを使用することをお勧めします)
- キー(同じ導出関数またはクリアキー)
- エンコーディング(キー、プレーンテキスト、暗号文などの同じエンコーディング)
- IV(暗号化中に生成され、復号化のために渡されます)
key
文字列が引数としてCryptoJS関数に渡される場合、encrypt()
その文字列は、暗号化に使用される実際のキーを導出するために使用されます。キー(有効なサイズは16、24、および32バイト)を使用する場合は、それをWordArrayとして渡す必要があります。
CryptoJS暗号化の結果は、OpenSSL形式の暗号文文字列です。そこから実際の暗号文を取得するには、そのciphertext
プロパティにアクセスする必要があります。
IVは、意味的に安全であるように、暗号化ごとにランダムである必要があります。そうすれば、攻撃者は、暗号文だけを見たときに、複数回暗号化された同じ平文が実際に同じ平文であるかどうかを判断できません。
以下は私が作った例です。
JavaScript:
var key = CryptoJS.enc.Utf8.parse('1234567890123456'); // TODO change to something with more entropy
function encrypt(msgString, key) {
// msgString is expected to be Utf8 encoded
var iv = CryptoJS.lib.WordArray.random(16);
var encrypted = CryptoJS.AES.encrypt(msgString, key, {
iv: iv
});
return iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64);
}
function decrypt(ciphertextStr, key) {
var ciphertext = CryptoJS.enc.Base64.parse(ciphertextStr);
// split IV and ciphertext
var iv = ciphertext.clone();
iv.sigBytes = 16;
iv.clamp();
ciphertext.words.splice(0, 4); // delete 4 words = 16 bytes
ciphertext.sigBytes -= 16;
// decryption
var decrypted = CryptoJS.AES.decrypt({ciphertext: ciphertext}, key, {
iv: iv
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
pycryptoを使用したPython2コード:
BLOCK_SIZE = 16
key = b"1234567890123456" # TODO change to something with more entropy
def pad(data):
length = BLOCK_SIZE - (len(data) % BLOCK_SIZE)
return data + chr(length)*length
def unpad(data):
return data[:-ord(data[-1])]
def encrypt(message, key):
IV = Random.new().read(BLOCK_SIZE)
aes = AES.new(key, AES.MODE_CBC, IV)
return base64.b64encode(IV + aes.encrypt(pad(message)))
def decrypt(encrypted, key):
encrypted = base64.b64decode(encrypted)
IV = encrypted[:BLOCK_SIZE]
aes = AES.new(key, AES.MODE_CBC, IV)
return unpad(aes.decrypt(encrypted[BLOCK_SIZE:]))
警告: python2とpycryptoはどちらも廃止されているため、python3とpycryptodomeに合うようにコードを調整する必要があることに注意してください。
その他の考慮事項:
パスフレーズをキーにしたいと思われます。パスフレーズは通常人間が読める形式ですが、キーはそうではありません。PBKDF2、bcrypt、scryptなどの機能を備えたパスフレーズからキーを取得できます。
上記のコードは認証がないため、完全に安全ではありません。認証されていない暗号文は、実行可能な攻撃や見過ごされているデータ操作につながる可能性があります。通常、encrypt-then-MACスキームは、HMAC-SHA256などの優れたMAC機能で使用されます。