SpringSecurity TextEncryptor: 共通鍵暗号化・復号


#はじめに
暗号化、復号はよく使う処理であり、SpringSecurityでは便利なインターフェイスが用意されており、簡単に使えますので、サンプルを作成してみます。

#暗号化、復号インターフェス
テキスト用：org.springframework.security.crypto.encrypt.TextEncryptor
バイト配列用：org.springframework.security.crypto.encrypt.BytesEncryptor 

#乱数生成インターフェス
テキスト用：org.springframework.security.crypto.keygen.StringKeyGenerator
バイト配列用：org.springframework.security.crypto.keygen.BytesKeyGenerator

#サンプル
```java
package sample.security;

import java.util.Base64;

import org.apache.commons.codec.binary.Hex;
import org.springframework.security.crypto.encrypt.BytesEncryptor;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.security.crypto.keygen.KeyGenerators;

public class Test {

	public static void main(String[] args) {

		// 平文
		String orginalText = "私は◯◯が好きです。";

		// 共通鍵
		String encryptSecrerKey = "GOV2dkHGQcE1ZcX8";

		// Salt：乱数生成
		byte[] bytes = KeyGenerators.secureRandom(16).generateKey();
		String salt = new String(Hex.encodeHexString(bytes));

		// CBC方式
		TextEncryptor cbcTextEncryptor = Encryptors.text(orginalText, salt);
		// 暗号化
		String encryptedCbcData = cbcTextEncryptor.encrypt(orginalText);
		System.out.println("暗号化した結果（AES-CBC)： " + encryptedCbcData);
		// 復号
		String decryptedCbcData = cbcTextEncryptor.decrypt(encryptedCbcData);
		System.out.println("復号した結果（AES-CBC)： " + decryptedCbcData);

		// GCM方式
		TextEncryptor aesGcmTextEncryptor = Encryptors.delux(encryptSecrerKey, salt);
		// 暗号化
		String encryptedData = aesGcmTextEncryptor.encrypt(orginalText);
		System.out.println("暗号化した結果（AES-GCM)： " + encryptedData);
		// 復号
		String decryptedData = aesGcmTextEncryptor.decrypt(encryptedData);
		System.out.println("復号した結果（AES-GCM)： " + decryptedData);

		// バイナリ(CBC)
		BytesEncryptor binaryEncryptor = Encryptors.standard(encryptSecrerKey, salt);
		// 暗号化
		String encryptedBinaryData = Base64.getEncoder()
				.encodeToString(binaryEncryptor.encrypt(orginalText.getBytes()));
		System.out.println("暗号化した結果（バイナリCBC)： " + encryptedBinaryData);
		// 復号
		byte[] decryptedBinaryData = binaryEncryptor.decrypt(Base64.getDecoder().decode(encryptedBinaryData));
		System.out.println("復号した結果（バイナリCBC)： " + new String(decryptedBinaryData));

		// バイナリ(GCM)
		BytesEncryptor aesGcmBinaryEncryptor = Encryptors.stronger(encryptSecrerKey, salt);
		// 暗号化
		String gcmEncryptedBinaryData = Base64.getEncoder()
				.encodeToString(aesGcmBinaryEncryptor.encrypt(orginalText.getBytes()));
		System.out.println("暗号化した結果（バイナリGCM)： " + gcmEncryptedBinaryData);
		// 復号
		byte[] gcmDecryptedBinaryData = binaryEncryptor.decrypt(Base64.getDecoder().decode(encryptedBinaryData));
		System.out.println("復号した結果（バイナリGCM)： " + new String(gcmDecryptedBinaryData));
	}
}


```

実行結果例：

>暗号化した結果（AES-CBC)： a34e20774314b85322de3eaf6c10f6990befe353d382cc449039524ffb7042b442f2a7a00beeddc94c8ad1495f6a0fba
復号した結果（AES-CBC)： 私は◯◯が好きです。
暗号化した結果（AES-GCM)： 1f5c89aeabf9f05a3cb286d1eca6e06ecd3259e9e52cea96d80e41d60614e436657317b7e69ad5b3e8672adaadd2434af69cbd36b516462908bef26d1ecf
復号した結果（AES-GCM)： 私は◯◯が好きです。
暗号化した結果（バイナリCBC)： zQg1LujXz6lpMwVoqNvG+ETtDbEC/LE0kq1LKJ+4d8ntbPDHDsAC0e5w6Eym7Hps
復号した結果（バイナリCBC)： 私は◯◯が好きです。
暗号化した結果（バイナリGCM)： gSFtQJCV0OSkjdg8sf+WHxYAFIdZrgb6MFWsPTmzau67lzFVW+ZJP36bWPQQ0p8/QZ9FIgQ7isZm4fIYt1g=
復号した結果（バイナリGCM)： 私は◯◯が好きです。


参考： https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/#spring-security-crypto-encryption-text

以上