Java实现RSA加密和验证
- 生成公私钥
- 基础的公钥加密私钥解密
- 自定义密钥加密及校验
- 加密
- 校验
- 测试验证
- 使用RSA进行数字签名和验证
RSA(Rivest–Shamir–Adleman)是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出,是目前广泛应用于加密和数字签名领域的一种加密算法。RSA的工作原理基于两个密钥:公钥和私钥,分别用于加密和解密数据,以及数字签名和验证。
以下是RSA的主要特点和一些常见的使用场景:
- 非对称加密: RSA是一种非对称加密算法,意味着它使用不同的密钥进行加密和解密。公钥用于加密数据,只有拥有相应私钥的用户才能解密它。这种非对称性使得RSA在安全通信中非常有用,因为
公钥可以公开分享,而私钥必须保密
。 - 数字签名和验证: RSA还可以用于
数字签名和验证
。发送方可以使用其私钥对消息进行签名,接收方可以使用发送方的公钥来验证签名。这确保了消息的完整性和来源认证。数字签名在网络安全、电子邮件认证和电子商务中广泛使用。 - 密钥交换: RSA可用于安全地交换对称密钥。
在两个通信方之间建立安全连接时,可以使用RSA加密传输对称密钥,然后使用该对称密钥进行快速的数据加密和解密
。这提高了性能并确保了密钥的安全交换。 - 安全通信: RSA可用于保护通信的机密性和完整性。通信双方可以使用对方的公钥来加密数据,以确保只有持有私钥的一方能够解密它。这在保护敏感信息传输时非常重要,例如,网上银行、电子商务和VPN连接。
- 数字证书:
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.auth0</groupId><artifactId>java-jwt</artifactId><version>3.8.3</version></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不对会报如下错误:
如果公私钥不匹配会报如下错误:
两种结果都说明解密失败。
正常执行返回结果:
使用RSA进行数字签名和验证
实现逻辑为使用私钥对数据进行签名
,然后使用公钥进行验证
。具体代码实现如下:
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("数字签名验证失败!");}}
}
结果输出如下:
本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位指出。
主页:共饮一杯无的博客汇总👨💻保持热爱,奔赴下一场山海。🏃🏃🏃