blog

フロントエンドとバックエンドの通信をゼロからAESで暗号化する

ECBの方法CBCの方法または問題の使用を推奨するためにここで推奨される、バックエンドは、フロントエンドの暗号化インターフェイスパラメータバックエンド復号化パラメータの方法の使用の成功を復号化しなかっ...

Mar 23, 2020 · 7 min. read
シェア

推奨

ECB方式はこちら

CBCのアプローチにはまだ問題があり、バックエンドはうまく復号化できませんでした。

使用方法

フロントエンド暗号化インターフェースパラメータ

バックエンドの復号化パラメータ、正常なデータを返します。

コントラクトアウト

npm i -S crypto-js

aesECBの暗号化

cryptoクラスを構築するための新しいcrypto.jsファイル

import CryptoJS from 'crypto-js'; class CryptoFile { constructor () { // this.key = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000'); // 16 this.iv = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000'); } // encrypt(word) { let words = CryptoJS.enc.Utf8.parse(word); let encrypted = CryptoJS.AES.encrypt(words, this.key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return encrypted.toString(); } // decrypt(word) { let decrypt = CryptoJS.AES.decrypt(word, this.key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } } export default new CryptoFile()

フロントエンドでの使用

導入クラス

import crypto from './crypto';

必要な場所で使用

暗号化と復号化が正常に行われるかどうかは、ご自身でテストすることができます。

let data = '暗号化されたデータ'
let encryptData = crypto.encrypt(JSON.stringify(data)); // 暗号化されたデータ
let decryptData = crypto.decrypt(encryptData) // 復号化されたデータ

バックエンドJavaの使用

javaはPkcs7をサポートしていません!

package com.CryptPacket;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/**
 * AES暗号化・復号化ツール
 * AES-128: keyjavaはAESしかサポートしていないようだ。-128
 */
public class AESCrypt {
 /**
 * AES ECB  
 * @param message 文字列を暗号化する必要がある
 * @param key  
 * @return 暗号化されたテキストをbase64でエンコードして返す。
 */
 public static String encryptECB(String message, String key) {
 final String cipherMode = "AES/ECB/PKCS5Padding";
 final String charsetName = "UTF-8";
 try {
 byte[] content = new byte[0];
 content = message.getBytes(charsetName);
 //
 byte[] keyByte = key.getBytes(charsetName);
 SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
 Cipher cipher = Cipher.getInstance(cipherMode);
 cipher.init(Cipher.ENCRYPT_MODE, keySpec);
 byte[] data = cipher.doFinal(content);
 final Base64.Encoder encoder = Base64.getEncoder();
 final String result = encoder.encodeToString(data);
 return result;
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 }
 catch (NoSuchAlgorithmException e) {
 e.printStackTrace();
 } catch (NoSuchPaddingException e) {
 e.printStackTrace();
 } catch (InvalidKeyException e) {
 e.printStackTrace();
 } catch (IllegalBlockSizeException e) {
 e.printStackTrace();
 } catch (BadPaddingException e) {
 e.printStackTrace();
 }
 return null;
 }
 /**
 * AES ECB  
 * @param messageBase64 暗号文、base64エンコーディング
 * @param key キーは暗号化と同じである。
 * @return 復号化されたデータ
 */
 public static String decryptECB(String messageBase64, String key) {
 final String cipherMode = "AES/ECB/PKCS5Padding";
 final String charsetName = "UTF-8";
 try {
 final Base64.Decoder decoder = Base64.getDecoder();
 byte[] messageByte = decoder.decode(messageBase64);
 //
 byte[] keyByte = key.getBytes(charsetName);
 SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
 Cipher cipher = Cipher.getInstance(cipherMode);
 cipher.init(Cipher.DECRYPT_MODE, keySpec);
 byte[] content = cipher.doFinal(messageByte);
 String result = new String(content, charsetName);
 return result;
 } catch (Exception e) {
 e.printStackTrace();
 }
 return null;
 }
 /**
 *  
 */
 public static void Test()
 {
 String key = "";
 String iv = "";
 String msg = "これはテストである これはテストである これはテストである";
 {
 String encrypt = AESCrypt.encryptCBC(msg, key, iv);
 System.out.println(encrypt);
 String decryptStr = AESCrypt.decryptCBC(encrypt, key, iv);
 System.out.println(decryptStr);
 }
 {
 String encrypt = AESCrypt.encryptECB(msg, key);
 System.out.println(encrypt);
 String decryptStr = AESCrypt.decryptECB(encrypt, key);
 System.out.println(decryptStr);
 }
 }
}

aesCBC暗号化

暗号クラスのフロントエンド構築

import CryptoJS from 'crypto-js'; class CryptoFile { constructor () { // this.key = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000'); // 16 this.iv = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000'); } // encrypt(word) { let words = CryptoJS.enc.Utf8.parse(word); let encrypted = CryptoJS.AES.encrypt(words, this.key, { iv: this.iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return encrypted.ciphertext.toString().toUpperCase(); } // decrypt(word) { let encryptedHexStr = CryptoJS.enc.Hex.parse(word); let words = CryptoJS.enc.Base64.stringify(encryptedHexStr); let decrypt = CryptoJS.AES.decrypt(words, this.key, { iv: this.iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } } export default new CryptoFile()

フロントエンドでの使用

導入クラス

import crypto from './crypto';

必要な場所で使用

暗号化と復号化が正常に行われるかどうかは、ご自身でテストすることができます。

let data = '暗号化されたデータ'
let encryptData = crypto.encrypt(JSON.stringify(data)); // 暗号化されたデータ
let decryptData = crypto.decrypt(encryptData) // 復号化されたデータ

バックエンドJavaの使用

javaはPkcs7をサポートしていません。

package com.CryptPacket;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/**
 * AES暗号化・復号化ツール
 * AES-128: keyjavaはAESしかサポートしていないようだ。-128
 */
public class AESCrypt {
 /**
 * AES CBC  
 * @param message 文字列を暗号化する必要がある
 * @param key  
 * @param iv IVキーの長さは、暗号化キーの長さと同じでなければならない。
 * @return 暗号化されたテキストをbase64でエンコードして返す。
 */
 public static String encryptCBC(String message, String key, String iv) {
 final String cipherMode = "AES/CBC/PKCS5Padding";
 final String charsetName = "UTF-8";
 try {
 byte[] content = new byte[0];
 content = message.getBytes(charsetName);
 //
 byte[] keyByte = key.getBytes(charsetName);
 SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
 //
 byte[] ivByte = iv.getBytes(charsetName);
 IvParameterSpec ivSpec = new IvParameterSpec(ivByte);
 Cipher cipher = Cipher.getInstance(cipherMode);
 cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
 byte[] data = cipher.doFinal(content);
 final Base64.Encoder encoder = Base64.getEncoder();
 final String result = encoder.encodeToString(data);
 return result;
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 }
 catch (NoSuchAlgorithmException e) {
 e.printStackTrace();
 } catch (NoSuchPaddingException e) {
 e.printStackTrace();
 } catch (InvalidKeyException e) {
 e.printStackTrace();
 } catch (InvalidAlgorithmParameterException e) {
 e.printStackTrace();
 } catch (IllegalBlockSizeException e) {
 e.printStackTrace();
 } catch (BadPaddingException e) {
 e.printStackTrace();
 }
 return null;
 }
 /**
 * AES CBC  
 * @param messageBase64 暗号文、base64エンコーディング
 * @param key キーは暗号化と同じである。
 * @param iv IVキーの長さは、暗号化キーの長さと同じでなければならない。
 * @return 復号化されたデータ
 */
 public static String decryptCBC(String messageBase64, String key, String iv) {
 final String cipherMode = "AES/CBC/PKCS5Padding";
 final String charsetName = "UTF-8";
 try {
 final Base64.Decoder decoder = Base64.getDecoder();
 byte[] messageByte = decoder.decode(messageBase64);
 //
 byte[] keyByte = key.getBytes(charsetName);
 SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
 //
 byte[] ivByte = iv.getBytes(charsetName);
 IvParameterSpec ivSpec = new IvParameterSpec(ivByte);
 Cipher cipher = Cipher.getInstance(cipherMode);
 cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
 byte[] content = cipher.doFinal(messageByte);
 String result = new String(content, charsetName);
 return result;
 } catch (Exception e) {
 e.printStackTrace();
 }
 return null;
 }
 /**
 *  
 */
 public static void Test()
 {
 String key = "";
 String iv = "";
 String msg = "これはテストである これはテストである これはテストである";
 {
 String encrypt = AESCrypt.encryptCBC(msg, key, iv);
 System.out.println(encrypt);
 String decryptStr = AESCrypt.decryptCBC(encrypt, key, iv);
 System.out.println(decryptStr);
 }
 {
 String encrypt = AESCrypt.encryptECB(msg, key);
 System.out.println(encrypt);
 String decryptStr = AESCrypt.decryptECB(encrypt, key);
 System.out.println(decryptStr);
 }
 }
}

Read next

徹底分析:オブジェクトの生成プロセスとメモリ割り当てメカニズム、読んだ後99%の人が理解する

メモリ割り当て:JVMはオブジェクトのためにメモリを割り当てます。オブジェクトが必要とするメモリ空間のサイズは、クラスがロードされた後に完全に決定することができ、その本質は、 "ポインタの衝突 "を決定するために、ヒープ内のメモリ空間の一部を開くことです:Javaのヒープメモリが絶対的なルールである場合、すべての使用メモリは、反対側の空きメモリの片側に配置され、ポインタの中央にある区切り点としてインジケータは、割り当てられたメモリは、単にそれを置くことです...

Mar 23, 2020 · 3 min read