公钥可以公开分享,而私钥必须保密
。数字签名和验证
。发送方可以使用其私钥对消息进行签名,接收方可以使用发送方的公钥来验证签名。这确保了消息的完整性和来源认证。数字签名在网络安全、电子邮件认证和电子商务中广泛使用。在两个通信方之间建立安全连接时,可以使用RSA加密传输对称密钥,然后使用该对称密钥进行快速的数据加密和解密
。这提高了性能并确保了密钥的安全交换。RSA也与数字证书一起使用,以验证网站的身份和安全性
。数字证书中包含了网站的公钥,通过验证证书的签名,用户可以确保他们正在与合法的网站通信,而不是受到中间人攻击。 RSA可以用于加密敏感数据
,然后将其存储在不安全的环境中,只有持有私钥的用户才能解密和访问数据。这对于存储密码、加密钱包和数据库等敏感数据非常有用。总的来说,RSA是一种强大且多用途的加密算法,广泛应用于网络通信、数据安全、数字签名、身份验证和加密存储等领域。然而,需要注意的是,RSA的性能较低,特别是对于长消息,因此在某些情况下,可能需要与对称加密算法结合使用,以提高性能。
本文主要讲述如何通过Java实现RSA加密与验证,应用场景为与其他平台对接接口时,通过RSA加密和解密验证请求的有效性,在对接时双方互换公钥
。
要实现加密和验证,首先你需要生成一对RSA密钥对,包括公钥和私钥。你可以使用Java的KeyPairGenerator
类来生成密钥对。实现代码如下:
package com.zjq.dailyrecord.security;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
/**
* RSA公私钥生成
* @author 共饮一杯无
*/
public class GenerateRSAKeys {
public static void main(String[] args) throws Exception {
// 创建一个RSA密钥对生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
// 设置密钥长度,通常为2048位
keyPairGenerator.initialize(2048);
// 生成RSA密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println("公钥: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));
System.out.println("私钥: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));
}
}
具体代码实现如下:
package com.zjq.dailyrecord.security;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
/**
* RSA加密和解密
* @author 共饮一杯无
*/
public class RSAEncryptionDecryption {
public static void main(String[] args) throws Exception {
String originalText = "Hello, RSA encryption and decryption!";
// 将公钥和私钥的Base64编码字符串转换为PublicKey和PrivateKey对象
String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhRJqXuMDyyc4b3+LrsZqwh+sZtV3n2pwjkWZ+SIkfW3GlrVPEQmGDbCB2xJ3coSc/IQ5ukkdh1ArTzf69kmn3zNZT34ZJgYjLNnvi9I2dBRZkARV2ERFhPYZsUt8WecSGt29SK22NsctMkSroRmsLRMUArmZ2r3knMrhy54PLvoeXwvDdpXC19EsioK5I7Huh29G+c3Bi8IWySR4/U2kpH+8CU2iZGiChwIZ6qqJgvaVbUuSdksHFnrVbl1LjqGKlb+Vos16UnluPlW4PGJMCfRYZcPqLSm728qT+jQFIUK17yAeznIvx5nccg6ke1GgnwhqeDicPuKnj4FKFm33/wIDAQAB";
String privateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFEmpe4wPLJzhvf4uuxmrCH6xm1XefanCORZn5IiR9bcaWtU8RCYYNsIHbEndyhJz8hDm6SR2HUCtPN/r2SaffM1lPfhkmBiMs2e+L0jZ0FFmQBFXYREWE9hmxS3xZ5xIa3b1IrbY2xy0yRKuhGawtExQCuZnaveScyuHLng8u+h5fC8N2lcLX0SyKgrkjse6Hb0b5zcGLwhbJJHj9TaSkf7wJTaJkaIKHAhnqqomC9pVtS5J2SwcWetVuXUuOoYqVv5WizXpSeW4+Vbg8YkwJ9Fhlw+otKbvbypP6NAUhQrXvIB7Oci/HmdxyDqR7UaCfCGp4OJw+4qePgUoWbff/AgMBAAECggEAWWJOSuAn6yy0DsjYlZQ3n59Q2V4n1M/VPOtpiluxsQKsswykSGhiQA3Am9timmyTWlaixAtap0plXPfYPdipxxYhtnCYCd9zfywAaKXR59THeCJBW1w4aiA4j8uJgoXgtmUdQJVWYKMXK73Onw60hS5ccZwjyTdmOR9Z3cCUqFNmX9EIAj9jUE9/nASNgnGNH5ULspaBUSH59B0D/2kNUexMrteShtlxKL73iFdptGu68NLk05GvghLG3o0HMJtOIyF+kj6x0BtPcD5xh7YxN6PTdrxnj4tmKsAesc38NBJphFFFmvxY5B9m9gKMOBQcGVW0By6AJLbE5Pj1w5GlMQKBgQDJ7+XQc3Q8VgXQZYpO2CA8Kygkls7GTsXwblB6u0aYT7uhht4Dwk2xCtkRWoUri6rVkcOKKY/SrU4GvVyK8E5AMHfOjTc1M6GQ6UOj760NUMqUwwzR45pUFKLtYq+gOlWqHz0Vu84DCQqU7nhJGqv5cMUoZRkTrqV6zPq/oWLa6QKBgQCosroKI3NfvkaTxYboNF8Bn6j1nzCrNW3VrtZvXXbeTWTxSgH01p45IcPPEfauQqHHzFSzrVP4HL9PNz8SYpwhS61i3PX5S2ftLRKsfOheYKWG7l5clu80SZfAcpXblp4QTZmHdp67dp2XMEFi/3VGDhZU/LCpLMvIUs/8MpmapwKBgBXALD3Gocd58Ihg14PkjZxNfbZrM/xyManTCAIgN9tiAzDDyRgYjqu6ImVXHa7yDUWRvMEd9urXVect8FDaz2LklZL+7OpjFEz6gxmeUEJ16Ewbsj7NSCs0SdRN4+LbRazcToUPxIHZMHWYNgaRw+JLPkE6mnffQN24RG3toSs5AoGBAIgoEI2kRTduXIpiL9t0gYXO9lCgVmio6+g+f+ZMemc78g/pWqDhI70a6m5TolTNhMO8wFRwvcgQc7wc6/QL0NXyvZOAoaq+2LeN3HeJLQcXXCIGe/ShAZmjGC8EjL052INyDktOSxkkyFbBZNThOCb9sbqQZIl2lVcut51mvaEbAoGBALwLpxIjj7N+dxkbScZCTWCgSPZ6t9y5rO9VkLtJ31aDAFqXljh4hphHhnsUq9z2pT3fo5mNRnaYutIixmzxQSQlzmjvnzFe+ZHFXMHm2l1fgOi5ByV9a/prUmyTuLuiwCf1/Q+E+qFPNnl5Actbamqk26zlMbZVTK6lrTM5PN+/";
PublicKey publicKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));
PrivateKey privateKey = KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)));
// 使用公钥加密数据
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = encryptCipher.doFinal(originalText.getBytes());
// 使用私钥解密数据
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);
String decryptedText = new String(decryptedBytes);
System.out.println("加密后的数据: " + Base64.getEncoder().encodeToString(encryptedBytes));
System.out.println("解密后的数据: " + decryptedText);
}
}
执行结果如下:
通过对接双方各自生成对应的公私钥,然后交换公钥和jwt用户key的形式实现加密和验证。
需要引入如下坐标依赖:
<dependency>
<groupId>com.auth0groupId>
<artifactId>java-jwtartifactId>
<version>3.8.3version>
dependency>
具体代码实现如下:
/**
* 加密
* @param dataJson
* @param priKey
* @param pubKey
* @return
*/
public static String encodeJwtToken(String dataJson, String priKey, String pubKey) {
try {
RSAPublicKey publicKey = defaultRSAPublicKey(pubKey);
RSAPrivateKey privateKey = defaultRSAPrivateKey(priKey);
//加密
Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
String token = JWT.create()
.withIssuer(RSAKeyUtil.USER_KEY)
//.withExpiresAt(expiresAt)
.withClaim("data", dataJson)
.sign(algorithm);
return token;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static RSAPublicKey defaultRSAPublicKey(String pubKey) throws Exception {
RSAPublicKey publicKey = getRSAPublicKey(pubKey);
return publicKey;
}
public static RSAPrivateKey defaultRSAPrivateKey(String priKey) throws Exception {
RSAPrivateKey privateKey = getRSAPrivateKey(priKey);
return privateKey;
}
public static RSAPublicKey getRSAPublicKey(String publicKey) throws Exception {
byte[] publicBytes = decryptBASE64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
return pubKey;
}
public static RSAPrivateKey getRSAPrivateKey(String privateKey) throws Exception {
byte[] clear = decryptBASE64(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey = (RSAPrivateKey) fact.generatePrivate(keySpec);
Arrays.fill(clear, (byte) 0);
return priKey;
}
/**
* 解码返回byte
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
/**
* 验签校验
* @param jwtToken
* @param priKey
* @param pubKey
* @return
* @throws Exception
*/
public static Boolean verify(String jwtToken, String priKey, String pubKey) throws Exception {
RSAPublicKey publicKey = RSAKeyUtil.defaultRSAPublicKey(pubKey);
RSAPrivateKey privateKey = RSAKeyUtil.defaultRSAPrivateKey(priKey);
//加密
Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
//解密
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(RSAKeyUtil.USER_KEY)
.build();
DecodedJWT jwt = null;
try{
jwt = verifier.verify(jwtToken);
}catch (Exception e){
e.printStackTrace();
return false;
}
return !StringUtils.isEmpty(jwt);
}
测试验证代码如下:
package com.zjq.dailyrecord.security;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Decoder;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
/**
* 商户公司验签加解密工具类
* @author 共饮一杯无
*/
public class RSAKeyUtil {
public final static String USER_KEY = "gongyinyibeiwu";
/**
* 验签校验
* @param jwtToken
* @param priKey
* @param pubKey
* @return
* @throws Exception
*/
public static Boolean verify(String jwtToken, String priKey, String pubKey) throws Exception {
RSAPublicKey publicKey = RSAKeyUtil.defaultRSAPublicKey(pubKey);
RSAPrivateKey privateKey = RSAKeyUtil.defaultRSAPrivateKey(priKey);
//加密
Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
//解密
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(RSAKeyUtil.USER_KEY)
.build();
DecodedJWT jwt = null;
try{
jwt = verifier.verify(jwtToken);
Claim subjectClaim = verifier.verify(jwtToken).getClaim("data");
String result = subjectClaim.asString();
System.out.println("解密结果:"+result);
}catch (Exception e){
e.printStackTrace();
return false;
}
return !StringUtils.isEmpty(jwt);
}
/**
* 加密
* @param dataJson
* @param priKey
* @param pubKey
* @return
*/
public static String encodeJwtToken(String dataJson, String priKey, String pubKey) {
try {
RSAPublicKey publicKey = defaultRSAPublicKey(pubKey);
RSAPrivateKey privateKey = defaultRSAPrivateKey(priKey);
//加密
Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
String token = JWT.create()
.withIssuer(RSAKeyUtil.USER_KEY)
//.withExpiresAt(expiresAt)
.withClaim("data", dataJson)
.sign(algorithm);
return token;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static RSAPublicKey defaultRSAPublicKey(String pubKey) throws Exception {
RSAPublicKey publicKey = getRSAPublicKey(pubKey);
return publicKey;
}
public static RSAPrivateKey defaultRSAPrivateKey(String priKey) throws Exception {
RSAPrivateKey privateKey = getRSAPrivateKey(priKey);
return privateKey;
}
public static RSAPublicKey getRSAPublicKey(String publicKey) throws Exception {
byte[] publicBytes = decryptBASE64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
return pubKey;
}
public static RSAPrivateKey getRSAPrivateKey(String privateKey) throws Exception {
byte[] clear = decryptBASE64(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey = (RSAPrivateKey) fact.generatePrivate(keySpec);
Arrays.fill(clear, (byte) 0);
return priKey;
}
/**
* 解码返回byte
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
public static void main(String[] args) {
// 当前平台的公钥
String ownPubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgBu0tGxKBDDUzEW498JYS5ibAtCTxXcw7fEALMek3D6mfbV9JOe10+Ukf9CSRYd4FEhjaq63Vy57mVs/Bmse9RQcv2AxyCBThwKJELA8kH2B8ulYkwlthEyz5/HJ49eLKljak9+b5Ya6uHTo3d5xIhXLc20IzW1O4QsxJVkmkTYS0jruFx3YrZdiiluawCYdmAUQ34JONS4cgsMrjwF8sRNsZ6Vu0trCttY94i2NYWJU1X0XCMWcYoTKLCenMa4XMoP+cgI1Q+6Ni4zZbCLMkwxo7rr+LBD6jpzrfi9/p15PdnzGFvOr+ZCQbKwemex+GuR86Xq/+ZozHK9YIjrcvQIDAQAB";
// 当前平台的私钥
String ownPriKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAG7S0bEoEMNTMRbj3wlhLmJsC0JPFdzDt8QAsx6TcPqZ9tX0k57XT5SR/0JJFh3gUSGNqrrdXLnuZWz8Gax71FBy/YDHIIFOHAokQsDyQfYHy6ViTCW2ETLPn8cnj14sqWNqT35vlhrq4dOjd3nEiFctzbQjNbU7hCzElWSaRNhLSOu4XHditl2KKW5rAJh2YBRDfgk41LhyCwyuPAXyxE2xnpW7S2sK21j3iLY1hYlTVfRcIxZxihMosJ6cxrhcyg/5yAjVD7o2LjNlsIsyTDGjuuv4sEPqOnOt+L3+nXk92fMYW86v5kJBsrB6Z7H4a5Hzper/5mjMcr1giOty9AgMBAAECggEANjoEEr8n0YBOAy2cLxvPvigZrWZWtqZOStnRxiK38RZ/6QRStbVzLP94pLXHxLCkLom5s2XDa57caLzL/86GKx1ZUdTJHbo5QRPcqvi+mjbWM9l8Sbka536ERLD/UXdijAlSdHeZiN2v2fZ6v7ex0cjB9tj3eeVEF1RieDm1bo+IffHsiDKidfJ3/VaG5rlOzxQvxq22R9BBh5I8C1N3OnDX+A4R4lqy85OTH5+IQcJh4Z4lDP2gMHMqDJDoa6yxOB4UdL9gmfWDx2TBD9Y0XbaILDRGHG/gdPPtUb7ybhuZ3GaRO0JfH6k0oeGo+g7dAOTkyZlkPFa++jgXf/YYrQKBgQC/Ar3E54fZAzdQv0f9uBtEhtgT4Um0OcXZin6WUqBbcYwH1XnATPxPpQG0SNpRDWlKiBVSGH2d9OcE6Rxtal3IbXR/nTtGQumWSFJ8cYIaQGS22Bynb5e5H5XXfgXZ+0qlGgMW3WeqJv7f47g/W14w8rBf4zCbQ44JALd3+CraBwKBgQCrshV+86pjEQfWzuuGGNOaVt4GEyomheGGxWd1vncDm6TwFYixiWEnt/0ZKRXjN7gmljv07u17WZHANRKeHJJ5mYTfge/ZKrrY5LUorWA3lpzTbFEdOof+ea7FUujfZ0VcFmRtEb1yyOwtxTNyUSuwJn9OzmbhsGZngUGtIbuyGwKBgBy4TsxSe8yXfTO47xwpGIB/PfIPR8O/hA4nks0Lc20Mb5+l636MlMts5gqzgY/6UkCQoZQMdqbPcgT8//c7rQo72u5tN8JiwTiFe1GWx5cm433SlMxgLRH6u88A9eRGsnyMorZHaBTfdCc52DQ+irUVaIuiX2aZC7wyzWNOfzL1AoGADEbJfrBRiI/ZLaTR9l6kEq8PZQPNyb9c5tQKl8Kso9dnLbt8cKVQCxT+xePIKtz7D9dCJjtHQ8CdyU6CLEgCuSse8xRJYA/MGGISCfyLmq3sPLnL+vkKbEmrE3TgLckmjnUTbTENiL2RFZy6Fvxy0T+PbsUXWh/Q0qnNVmHJF+0CgYBstz+ESSvKJhSCNpWccnsCNyza9gy1KrgHFQn8RbJ/ss4s21iXEBZYEex2sjwFUZmH2xUxeV45x2zOyCrxJrHqgaA+0og8CmD5mqLDpliiBOpIQr2Du7DLMUAQDZ4oJvkul/ADQ3HJcCcMqQs7xLI0PzIKHjhh/IeWtxbQDDp72g==";
// 对接平台公钥
String otherPubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4A6SXgt/nNh76Hn85pZxvh2mRv2y4VWfrwM8lFv7urzJ3xt5FocujjEoQT3Q5jeByxiZaOmPk6mfpTTCsel5vGZqLtM8mrNKoPrXiKuq0U0sWUpXdlRLaFV+SMujTsuYl76get9kLVjwXRu4qlhtZlLlWcLpNu6wEu1JwY8Kl9BDP46X0J+IoL+f9iB0i8PAw71n6NJmGk4bvYAjwnMd9zMPdY+s9hfbv2OILdGkSAcaZGoan03HK8u5JBikMZOvhXHkNkgBtRX8ATqCbYK4fTAC70RdOwqbyOhcW/qie18KnfZJsINb7cPfN406wIK6rMapCx7RJ7eu7Ey0Hm8GGQIDAQAB";
// 对接平台私钥
String otherPriKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgDpJeC3+c2HvoefzmlnG+HaZG/bLhVZ+vAzyUW/u6vMnfG3kWhy6OMShBPdDmN4HLGJlo6Y+TqZ+lNMKx6Xm8Zmou0zyas0qg+teIq6rRTSxZSld2VEtoVX5Iy6NOy5iXvqB632QtWPBdG7iqWG1mUuVZwuk27rAS7UnBjwqX0EM/jpfQn4igv5/2IHSLw8DDvWfo0mYaThu9gCPCcx33Mw91j6z2F9u/Y4gt0aRIBxpkahqfTccry7kkGKQxk6+FceQ2SAG1FfwBOoJtgrh9MALvRF07CpvI6Fxb+qJ7Xwqd9kmwg1vtw983jTrAgrqsxqkLHtEnt67sTLQebwYZAgMBAAECggEAHh23TM7M21854HitJq1oIn7Hv9kP9zvUF+kedm6aunHvzH5b20xWVKSE3agacSda2dq3nCNwug9dtw4NcW6Jf2pgsWSRS9X3nQW6fNNeRX3TDTlx4iTYcfCz5cMBc3DoVNU5qupmA7ZlsI4uVy9FnTBdRaBuSoTww8qDVHIOoXMLenXArosyQEytxEL1uBGF8xijBWC5CGQfLjegcqYiVJ7Bl5kGXGwo0q0dzTabx/P4sH1BBRWMkTEUgfBZs4QvFiTfCIB0/X44cIHpokBnaeYGKX7aVVDIRni1ot3gzYDgBnIGM9ZY/CjLn0mrnZciVr8SemTyobGf/GlPoID+xQKBgQD4HLuAQR1SqiNwuB+lDz0hYqFL/r3VvEa4Wety7lznppz9EWeDEnN89bk9+RXxq+cSg7EwGdI+LGNeZpShpCBrb/93VYN/kohywb6vgZJ3gjT50J+8mmvxm0cE61xZ+VGkAKn1QqO6voF17mOcHD4k/h1je0SVj7d40q2QbQwKWwKBgQDnLhCF9JZE23gPP2CCccQlA4QHR89i6YwQpFWyINIJA/p42cdVPErprQqsBDBoV5sk9GX9X08GBsU2tDDvOxCsQjPShe/pVSvdCg8aFnQzi5r8lEhGpirH16N9LHRx2dsFvoN/h+zqbuF4MRdmsPmUb6UFs3CnGfvraWo/OCATmwKBgAsS1TeDMHjZCR3lydvHE1ZjHYnTw8s/TPS7ZqvJgbIBGK6e0TzjXO4t1Wezr0wK/RQxdn4MGPsXZhP3hhi0x5Gj/QXpdiYCdz6P8R/KK6xTzmN78TUsuzacVI4epw+I9iDYur0sjTwvdn259w4noIpsIQmoncYDFRA6bu6sP0ZTAoGBAIra/Em5c1jAigh+hLVVJ/8jcXX+B+7dYKfOTTrEw+NuZE+aX0QvBr/8k+BmU70YgbNcqLXbPVfdUS9eY9YNoCIXUZEtqcB4y/PkStXcjsc3H0x+tDrbK+8E8soInZiUxh1ZJRrAxei52OuccPXZbs9dj70w3oU/8jSgCJUYXQvpAoGBAIv+AsEpjKnSCukCftO4XBdRFgyf4+XXbnqOqThHzUlSd02qk2aijjs9XFMtnoBobqOM/jDhh6uYSX5vWJtrarlgX7cvKD9xDroC54RmDnDfOl0CfN5DaffofsD8+z6MSQU1FN1PYigkqfDHCKCFRL4Hp90PvGuynejhAl8x1OfC";
String jsonStr = "{\n" +
" \"name\":\"共饮一杯无\"\n" +
"}";
// 1.先加密
String jwtToken = RSAKeyUtil.encodeJwtToken(jsonStr,ownPriKey,otherPubKey);
System.out.println(jwtToken);
try {
// 2.解密
Boolean verify = RSAKeyUtil.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJkYXRhIjoie1xuICAgIFwibmFtZVwiOlwi5YWx6aWu5LiA5p2v5pegXCJcbn0iLCJpc3MiOiJnb25neWlueWliZWl3dSJ9.BGat7UWtc75ZyTMoySrtBOLyED9iNBOJOvw198_yg6ZbjCuitFIvl4p7qs9v2oo3BoAPWH8gKLQsLLhsUQ6p9thcCimB0ClTJkxQlxd_2I8J-fli2Jmc09I53mIptNOtfB_zDn5UuXyVtB5-aD_mUs9xLXkEb8DJbMl4__LHDQyr1v3ixh0rq_e5LaY0ZOfSq2l06MaSAssdKQRvN_H0snO0KJkodcPktfRr4hOXI_ZvcbZHgiuv6JUpbp6x7T9BWMvixD7TTd-lqqm2OsqGOCtWJ4URSJmjYdLDswHY89jNzfVHrQ6exuUIeranWJoRf2-smE8KpLAN8kxs1o1Rpg"
,otherPriKey,ownPubKey);
System.out.println(verify);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果用户key不对会报如下错误:
如果公私钥不匹配会报如下错误:
两种结果都说明解密失败。
正常执行返回结果:
实现逻辑为使用私钥对数据进行签名
,然后使用公钥进行验证
。具体代码实现如下:
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;
/**
* RSA数字签名实现
* @author 共饮一杯无
*/
public class RSASignatureVerification {
public static void main(String[] args) throws Exception {
String data = "待签署及核实的资料。";
// 将公钥和私钥的Base64编码字符串转换为PublicKey和PrivateKey对象
String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhRJqXuMDyyc4b3+LrsZqwh+sZtV3n2pwjkWZ+SIkfW3GlrVPEQmGDbCB2xJ3coSc/IQ5ukkdh1ArTzf69kmn3zNZT34ZJgYjLNnvi9I2dBRZkARV2ERFhPYZsUt8WecSGt29SK22NsctMkSroRmsLRMUArmZ2r3knMrhy54PLvoeXwvDdpXC19EsioK5I7Huh29G+c3Bi8IWySR4/U2kpH+8CU2iZGiChwIZ6qqJgvaVbUuSdksHFnrVbl1LjqGKlb+Vos16UnluPlW4PGJMCfRYZcPqLSm728qT+jQFIUK17yAeznIvx5nccg6ke1GgnwhqeDicPuKnj4FKFm33/wIDAQAB";
String privateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFEmpe4wPLJzhvf4uuxmrCH6xm1XefanCORZn5IiR9bcaWtU8RCYYNsIHbEndyhJz8hDm6SR2HUCtPN/r2SaffM1lPfhkmBiMs2e+L0jZ0FFmQBFXYREWE9hmxS3xZ5xIa3b1IrbY2xy0yRKuhGawtExQCuZnaveScyuHLng8u+h5fC8N2lcLX0SyKgrkjse6Hb0b5zcGLwhbJJHj9TaSkf7wJTaJkaIKHAhnqqomC9pVtS5J2SwcWetVuXUuOoYqVv5WizXpSeW4+Vbg8YkwJ9Fhlw+otKbvbypP6NAUhQrXvIB7Oci/HmdxyDqR7UaCfCGp4OJw+4qePgUoWbff/AgMBAAECggEAWWJOSuAn6yy0DsjYlZQ3n59Q2V4n1M/VPOtpiluxsQKsswykSGhiQA3Am9timmyTWlaixAtap0plXPfYPdipxxYhtnCYCd9zfywAaKXR59THeCJBW1w4aiA4j8uJgoXgtmUdQJVWYKMXK73Onw60hS5ccZwjyTdmOR9Z3cCUqFNmX9EIAj9jUE9/nASNgnGNH5ULspaBUSH59B0D/2kNUexMrteShtlxKL73iFdptGu68NLk05GvghLG3o0HMJtOIyF+kj6x0BtPcD5xh7YxN6PTdrxnj4tmKsAesc38NBJphFFFmvxY5B9m9gKMOBQcGVW0By6AJLbE5Pj1w5GlMQKBgQDJ7+XQc3Q8VgXQZYpO2CA8Kygkls7GTsXwblB6u0aYT7uhht4Dwk2xCtkRWoUri6rVkcOKKY/SrU4GvVyK8E5AMHfOjTc1M6GQ6UOj760NUMqUwwzR45pUFKLtYq+gOlWqHz0Vu84DCQqU7nhJGqv5cMUoZRkTrqV6zPq/oWLa6QKBgQCosroKI3NfvkaTxYboNF8Bn6j1nzCrNW3VrtZvXXbeTWTxSgH01p45IcPPEfauQqHHzFSzrVP4HL9PNz8SYpwhS61i3PX5S2ftLRKsfOheYKWG7l5clu80SZfAcpXblp4QTZmHdp67dp2XMEFi/3VGDhZU/LCpLMvIUs/8MpmapwKBgBXALD3Gocd58Ihg14PkjZxNfbZrM/xyManTCAIgN9tiAzDDyRgYjqu6ImVXHa7yDUWRvMEd9urXVect8FDaz2LklZL+7OpjFEz6gxmeUEJ16Ewbsj7NSCs0SdRN4+LbRazcToUPxIHZMHWYNgaRw+JLPkE6mnffQN24RG3toSs5AoGBAIgoEI2kRTduXIpiL9t0gYXO9lCgVmio6+g+f+ZMemc78g/pWqDhI70a6m5TolTNhMO8wFRwvcgQc7wc6/QL0NXyvZOAoaq+2LeN3HeJLQcXXCIGe/ShAZmjGC8EjL052INyDktOSxkkyFbBZNThOCb9sbqQZIl2lVcut51mvaEbAoGBALwLpxIjj7N+dxkbScZCTWCgSPZ6t9y5rO9VkLtJ31aDAFqXljh4hphHhnsUq9z2pT3fo5mNRnaYutIixmzxQSQlzmjvnzFe+ZHFXMHm2l1fgOi5ByV9a/prUmyTuLuiwCf1/Q+E+qFPNnl5Actbamqk26zlMbZVTK6lrTM5PN+/";
PublicKey publicKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));
PrivateKey privateKey = KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)));
// 使用私钥进行数字签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes());
byte[] signatureBytes = signature.sign();
System.out.println("数字签名: " + Base64.getEncoder().encodeToString(signatureBytes));
// 使用公钥进行验证
signature.initVerify(publicKey);
signature.update(data.getBytes());
boolean verified = signature.verify(signatureBytes);
if (verified) {
System.out.println("数字签名验证成功!");
} else {
System.out.println("数字签名验证失败!");
}
}
}
结果输出如下:
本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位指出。
主页:共饮一杯无的博客汇总👨💻保持热爱,奔赴下一场山海。🏃🏃🏃