签名——SHA256-RSA2048
生成私钥、公钥
$ openssl OpenSSL> OpenSSL> OpenSSL> genrsa -out private_key.pem 2048 Generating RSA private key, 2048 bit long modulus (2 primes) ....................................+++++ ......................................................+++++ e is 65537 (0x010001) OpenSSL> OpenSSL> rsa -in private_key.pem -pubout -out public_key.pem writing RSA key OpenSSL> exit
-rw-r--r-- 1 admin 197121 1702 Sep 22 08:16 private_key.pem
-rw-r--r-- 1 admin 197121 460 Sep 22 08:16 public_key.pem
#生成私钥
openssl genrsa -out private_key.pem 2048
生成公钥 openssl rsa -in private_key.pem -pubout -out public_key.pem
#私钥转 PKCS#8 格式 openssl pkcs8 -topk8 -in private_key.pem -out private_key_pkcs8.pem -nocrypt
应用私钥对待签名串进行SHA256-RSA2048签名,并对签名结果进行Base64编码得到签名值。
Java类
package com.utils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* SHA256RSA 签名、验签
*/
public class Sha256RsaUtil {
public static String sign(byte[] privateKeyBytes, String data) throws Exception {
// 读取私钥文件
byte[] keyBytes = privateKeyBytes;
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// 对数据进行 SHA256-RSA2048 签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
byte[] signBytes = signature.sign();
// 对签名结果进行 Base64 编码
return Base64.getEncoder().encodeToString(signBytes);
}
public static boolean verify(byte[] publicKeyBytes, String responseData, String byteSignature) throws Exception {
// 读取公钥文件
byte[] keyBytes = publicKeyBytes;
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// 分割应答数据
String[] responseParts = responseData.split("\n");
String responseTimestamp = responseParts[0];
String responseNonceStr = responseParts[1];
String responseBody = responseParts[2];
// 构造待验签数据
String unsignedString = responseTimestamp + "\n" + responseNonceStr + "\n" + responseBody;
// 解码签名值
byte[] signBytes = Base64.getDecoder().decode(byteSignature.getBytes());
// 验证签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(unsignedString.getBytes(StandardCharsets.UTF_8));
return signature.verify(signBytes);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2021-09-22 算法——回溯算法 (Back Tracking) (转)
2018-09-22 关于java 线程的停止同时用 interrupt 和 join 的作用