言語を超えた暗号化、復号をちょっと試してみたかったので、RubyでAES-256-CBCにより暗号化してJavaScriptで復号するっていうのをやってみた。
特に実用的ではないです。ただのロマンです。
バージョン情報
- Ruby 2.6.0
- node 11.5.0
- crypto-js 3.1.9-1
コード
Rubyで暗号化
共通鍵は定数KEY
に格納しているやつです。とても短いですね。
暗号化する文章は定数TEXT
に入れました。これを暗号化し、JavaScript側で復号できれば成功です。
require 'openssl'
require 'base64'
KEY = 'NpeinfW#*&$T@<A>'
TEXT = 'ヘローワールド'
digest = Digest::SHA256.new
digest.update(KEY)
enc = OpenSSL::Cipher.new('aes-256-cbc')
enc.encrypt
enc.key = digest.digest
enc.iv = iv = enc.random_iv
crypted = enc.update(TEXT) + enc.final
crypted_base64 = Base64.encode64(crypted).gsub("\n", '')
iv_base64 = Base64.encode64(iv).gsub("\n", '')
puts crypted_base64
puts iv_base64
これをruby encrypt.rb
コマンドで実行すると、次の出力を得られます。
この暗号化文字列とIVはメモっておきます。
abgECXtT0eWoBNxWnqQcWYr2DS7xWJGr+PvwiX5O97M=
QdxP21s4lyQCGbWDlJrSvw==
JavaScriptで復号
復号にはcrypto-jsを使用しました。
共通鍵と、Rubyの出力である暗号化された文字列とIVを設定します。
const SHA256 = require('crypto-js/sha256')
const Base64 = require('crypto-js/enc-base64')
const AES = require('crypto-js/aes')
const Utf8 = require('crypto-js/enc-utf8')
const cryptedBase64 = 'abgECXtT0eWoBNxWnqQcWYr2DS7xWJGr+PvwiX5O97M='
const ivBase64 = 'QdxP21s4lyQCGbWDlJrSvw=='
const key = SHA256('NpeinfW#*&$T@<A>')
const crypted = Base64.parse(cryptedBase64)
const iv = Base64.parse(ivBase64)
const decrypted = AES.decrypt({ciphertext: crypted}, key, {iv: iv})
const encryptedText = Utf8.stringify(decrypted)
console.log(encryptedText)
これをnode decrypt.js
で実行すると次の出力がされました。
ヘローワールド
成功ですね。