以下は、Spring Boot を使用して RSA 暗号化、復号化、署名、検証を実装する RSAUtil クラスのサンプル コードです。
```
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public class RSAUtil {
private static final String RSA_ALGORITHM = "RSA";
//这个函数是自己随机生成一个rsa的公私密钥对,一般情况下我们是从配置文件或者redis读取密钥对的,也就是这个函数用不到。
public static Map<String, String> generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
keyPairGenerator.initialize(2048);//2048太长了,一般1024即可
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String publicKeyString = Base64Utils.encodeToString(publicKey.getEncoded());
String privateKeyString = Base64Utils.encodeToString(privateKey.getEncoded());
return Map.of("publicKey", publicKeyString, "privateKey", privateKeyString);
//这里map.of如果用不了,就老老实实new个map.put去加载<k,v>
}
public static String encrypt(String data, String publicKeyString) throws Exception {
byte[] publicKeyBytes = Base64Utils.decodeFromString(publicKeyString);
PublicKey publicKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64Utils.encodeToString(encryptedBytes);
}
public static String decrypt(String encryptedData, String privateKeyString) throws Exception {
byte[] privateKeyBytes = Base64Utils.decodeFromString(privateKeyString);
PrivateKey privateKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(Base64Utils.decodeFromString(encryptedData));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
public static String sign(String data, String privateKeyString) throws Exception {
byte[] privateKeyBytes = Base64Utils.decodeFromString(privateKeyString);
PrivateKey privateKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
byte[] signatureBytes = signature.sign();
return Base64Utils.encodeToString(signatureBytes);
}
public static boolean verify(String data, String signature, String publicKeyString) throws Exception {
byte[] publicKeyBytes = Base64Utils.decodeFromString(publicKeyString);
PublicKey publicKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Signature verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(publicKey);
verifier.update(data.getBytes(StandardCharsets.UTF_8));
byte[] signatureBytes = Base64Utils.decodeFromString(signature);
return verifier.verify(signatureBytes);
}
public static String sortParams(Map<String, String> params) {
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
String sortedParams = Arrays.stream(keys)
.map(key -> key + "=" + params.get(key))
.collect(Collectors.joining("&"));
return sortedParams;
}
}
```
このクラスには 5 つの静的メソッドがあります。
- `generateKeyPair()`
- このメソッドは RSA 公開鍵と秘密鍵のペアを生成するために使用され、戻り値は公開鍵と秘密鍵を含む Map です。
- `encrypt(String data, String publicKeyString)`:
このメソッドは、公開キーを使用してデータを暗号化し、暗号化された Base64 エンコード文字列を返すために使用されます。
- `decrypt(String encryptedData, String privateKeyString)`:
このメソッドは、秘密キーを使用して暗号化されたデータを復号化し、復号化された文字列を返すために使用されます。
- `sign(文字列データ, 文字列privateKeyString)`:
このメソッドは、秘密キーでデータに署名し、署名された Base64 エンコード文字列を返すために使用されます。
- `verify(文字列データ, 文字列署名, 文字列 publicKeyString)`:
このメソッドは、公開キーを使用して署名を検証するために使用され、検証に合格した場合は true を返し、そうでない場合は false を返します。
さらに、このクラスには静的メソッド `sortParams(Map<String, String> params)` もあり、これは Map 内のパラメータをソートし、署名に使用するソートされた文字列を返すために使用されます。
使用例を次に示します。
```
public static void main(String[] args) throws Exception {
// 生成公私密钥对,或者不生成,直接从配置文件载入pub&pri的2个字符串值
Map<String, String> keyPair = RSAUtil.generateKeyPair();
String publicKey = keyPair.get("publicKey");
String privateKey = keyPair.get("privateKey");
// 加密解密示例
String data = "Hello, world!";
String encryptedData = RSAUtil.encrypt(data, publicKey);
String decryptedData = RSAUtil.decrypt(encryptedData, privateKey);
System.out.println("原始数据:" + data);
System.out.println("加密后数据:" + encryptedData);
System.out.println("解密后数据:" + decryptedData);
// 签名验签示例,Map.of可以改成new map.put(k,v)
Map<String, String> params = Map.of(
"timestamp", "1621005751",
"nonce", "123456",
"data", "Hello, world!"
);
String sortedParams = RSAUtil.sortParams(params);
String signature = RSAUtil.sign(sortedParams, privateKey);
boolean verified = RSAUtil.verify(sortedParams, signature, publicKey);
System.out.println("排序后的参数:" + sortedParams);
System.out.println("签名结果:" + signature);
System.out.println("验签结果:" + verified);
}
```
このサンプル コードでは、まず「generateKeyPair()」メソッドを使用して RSA 公開鍵と秘密鍵のペアを生成し、その公開鍵と秘密鍵を変数「publicKey」と「privateKey」に格納します。次に、`encrypt()` メソッドを使用して文字列「Hello, world!」を暗号化し、次に `decrypt()` メソッドを使用して暗号化されたデータを復号し、最後に暗号化前後の文字列と文字列を出力します。復号化後。次に、`sortParams()` メソッドを使用して 3 つのパラメータを含む Map を並べ替え、次に `sign()` メソッドを使用して並べ替えられたパラメータに署名し、`verify()` メソッドを使用して署名を検証します。最後に、ソートされたパラメータ、署名結果、署名検証結果を出力します。
この例があなたのニーズを達成するのに役立つことを願っています。