各言語で暗号化。
やってみると、暗号化後の文字列が各言語で違ってしまったりして、意外とハマったりします。
ここでは、Java/JavaScript/C#を取り上げてみます。
暗号化
Java
まずは、Java。
Crypto.java
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public final class Crypto {
private static final String KEY = "1234567890abcdef";
private static final String IV = "abcdef1234567890";
private Crypto() {
}
private static Cipher createCipher(int mode) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), "AES");
IvParameterSpec iv = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
cipher.init(mode, key, iv);
return cipher;
}
public static String encrypt(String text) {
try {
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE);
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(cipher.doFinal(text.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String decrypt(String text) {
try {
Cipher cipher = createCipher(Cipher.DECRYPT_MODE);
Base64.Decoder decoder = Base64.getDecoder();
return new String(cipher.doFinal(decoder.decode(text)));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
JavaScript
次にJavaScript。実行環境はNode.jsです。
Crypto.js
const crypto = require('crypto')
const KEY = '1234567890abcdef'
const IV = 'abcdef1234567890'
function createCipher(mode) {
return crypto[mode]('aes-128-cbc', KEY, IV)
}
function encrypt(text) {
const cipher = createCipher('createCipheriv')
const encrypted = cipher.update(text);
return Buffer.concat([encrypted, cipher.final()]).toString('base64')
}
function decrypt(text) {
const buf = Buffer.from(text, 'base64')
const cipher = createCipher('createDecipheriv')
const decrypted = cipher.update(buf);
return Buffer.concat([decrypted, cipher.final()]).toString('utf-8')
}
C#
最後にC#。
Crypto.cs
using System;
using System.Security.Cryptography;
using System.Text;
public sealed class Crypto
{
private const string KEY = "1234567890abcdef";
private const string IV = "abcdef1234567890";
private Crypto()
{
}
private static AesManaged CreateAesManaged()
{
AesManaged aes = new AesManaged();
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Mode = CipherMode.CBC;
aes.IV = Encoding.UTF8.GetBytes(IV);
aes.Key = Encoding.UTF8.GetBytes(KEY);
aes.Padding = PaddingMode.PKCS7;
return aes;
}
public static string Encrypt(string text)
{
AesManaged aes = CreateAesManaged();
byte[] byteText = Encoding.UTF8.GetBytes(text);
byte[] encryptText = aes.CreateEncryptor().TransformFinalBlock(byteText, 0, byteText.Length);
return Convert.ToBase64String(encryptText);
}
public static string Decrypt(string text)
{
AesManaged aes = CreateAesManaged();
byte[] src = System.Convert.FromBase64String(text);
byte[] dest = aes.CreateDecryptor().TransformFinalBlock(src, 0, src.Length);
return Encoding.UTF8.GetString(dest);
}
}
結果
暗号化(encrypt
)すると、以下の結果になります。
- ""(空文字)=> 0e8Yyuobp55/giEyC01lbg==
- alz1590-'$ => cMgaJ1X/cVENp+rnMo/8Kw==
- あむんアムンアムン亜無漚錡𠀋𪚲 => jXw9bzISBZsndhcrJx/gJU7ltBzSp34xn6CL3xBbNE2yC0FhQBisP27WOXan/W2o
復号(decrypt
)すると、元の文字列が得られます。
補足
-
IV
は初期化ベクトルです。同じデータであっても違う暗号文にするための文字列です。 -
KEY
/IV
は長さに決まりがあるので注意。