用Java实现RSA加解密及签名和验签——.pem文件格式秘钥
Posted 依米欧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Java实现RSA加解密及签名和验签——.pem文件格式秘钥相关的知识,希望对你有一定的参考价值。
一、***.pem文件格式的秘钥(获取秘钥:可通过文件读取内容或者直接打开文件复制内容),我这里是打开文件复制秘钥直接使用
1、准备秘钥对,通过openssl生成秘钥对,生成秘钥可参考:https://www.cnblogs.com/ouyanxia/p/12427955.html
A_RSA_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnPzYKf20JIzaEEkeQTnDAkM1s+nzPbRIA2vU/FOQ47XGIa16lFQ//mxb2ichRF/YGRrBseoK4qxs5zAdNJwXWxQE5nsLzQvSsnQetROczUAdrNVMA4p+rySycYbMF3WK3TFODh1XUZ6KPPZ41PIABFPuqRsK3gHOhAtSmx8LP4cvgnFbCNQl7n7lWmEaTrSOiv+Ld8XlBIIG+jbIzDh6pHCYVsQBkhhC16awxNsbMVKAuGxpDO7OqEqOcmpTODDUuI99YBIuWrxHSHEOGDyK4FlGn9Ryd0fBLMsPPPfxZkC/KiJHIXm/k3I2CtR7E0+iQz3M5nogAsGzBIdVmcod/AgMBAAECggEBAMg2vG1eYmM077BtuzRAFfND6/hc788P2jSPXyMczXRUcKXygGFh2RYvizQtmxhLLKHGdl2VvLRywQHLms676JxIuYTP5m6EHB+PXeQw8hRFSAcUhicQD7rGVS+Yj02Wni+hj/UjKbbbe62VZfMlzJYjOrn0xgXm2zYeo0s7TXp5mWkmhhy3SVbz7AGDOJ4uZo8Hh3ORm6SfDChBi5fOBqH+4gBASQUPgTUczWZuq/5MhBHTTFPjief5mY7uSD8algBdlPnXeqGO1NiCE7/3m/PddI+xX35JyfwvosaHq3GKWAoAEEOVMWyG8tsveSMNV2YsPCj14LPPrbo9umwfCvECgYEA+ybodq1Fmt82qQR+BAyjGrNUOVQe0MtghrGvuH7yjJf9dzoU0+nmF7qS64Rya6udD+nDE34pH+Wz7Y22pfX6GL2Qino+vLLVTjXVJ7oSFt17l3V8WiMBBFdsr0aCQTlP/rmlS+Gzx+DP9BzIf3EXmYxcZMVYBLN8lJbogMHF3wMCgYEA67XwshfsuY6yxVAFjQIs8VU2ROxzp8FO0zKPCk8xXm96ikyidQ5slWzJ7HfogFqCTB8ZOT2kedF5WZyxNSykcipyxPcgSFtkyxNhkp/bwC2KS0JxePftaDGzzb7fAM61SfWunKTDTa0CQJTKMnDJ13Fcv9Z8HzCBt7DBN/DZ/tUCgYEA2SAwBLmT3WpwRPq/Pxz1vVWf0Ngqs/O/hXMEKYqGgom79WFfND2YUJdaAQbGLNN2u5UqsyV0xEC/pvXHG/9lshHgbfd1WYl5412i4+93SBE+khhd40czz98M9RMN9PlpcRxqDQoZdQmkfrSLmbHZ50NzdSMvDxFk+MjmRLpBKKUCgYEAzMenkoI4lslDxSqNeAFA3HYEjQLERCUsf034eaNtp7bARnDn3zyl13fJQhi2tPRtKQcHmfRU9cSoYdNBHYpoYAtC5J4yvMoyGj//UCxz9VVbRaE3BjqXViOAK6q9AW2UkOnSRqLaTpyVTVg3BnV41iTVyJDmCw7QU69LXndwXPUCgYBAambp9pl16WnjXNq2FJ+hlkbDDzWxSfHx0MVDmnd7Ptko0mMPCDjXP/3k18N2I0fucsVMDnxUnzi+bopp/MPunWPFKvBhjCG6r2C6NP7GjU1YyQv7cYJ1/FVQ1W4Sb/HWH0d3OLHR1YddOwvJ0o2T1TFfJ5hRUAlGyr07z4SNDA==-----END PRIVATE KEY----- A_RSA_PUBILC_KEY=-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5z82Cn9tCSM2hBJHkE5wwJDNbPp8z20SANr1PxTkOO1xiGtepRUP/5sW9onIURf2BkawbHqCuKsbOcwHTScF1sUBOZ7C80L0rJ0HrUTnM1AHazVTAOKfq8ksnGGzBd1it0xTg4dV1Geijz2eNTyAART7qkbCt4BzoQLUpsfCz+HL4JxWwjUJe5+5VphGk60jor/i3fF5QSCBvo2yMw4eqRwmFbEAZIYQtemsMTbGzFSgLhsaQzuzqhKjnJqUzgw1LiPfWASLlq8R0hxDhg8iuBZRp/UcndHwSzLDzz38WZAvyoiRyF5v5NyNgrUexNPokM9zOZ6IALBswSHVZnKHfwIDAQAB-----END PUBLIC KEY-----
2、编写RSAUtil类
import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.apache.tomcat.util.codec.binary.Base64; public class RSAUtil { public static RSAPublicKey publicKey; public static RSAPrivateKey privateKey; public static void configure(PemConfig config) { try { RSAUtil.publicKey = (RSAPublicKey) getRSAPublicKey(config.getRsa_public_key()); RSAUtil.privateKey = (RSAPrivateKey)getRSAPrivateKey(config.getRsa_private_key()); } catch (Exception e) { e.printStackTrace(); } } /** * 私钥签名(A用私钥签名) * @param source * @param pkcs8_rsa_private_key * @return */ public static String doSignBySHA1withRSA(String source) { byte[] sourceData = source.getBytes(); String result = null; try { Signature sign = Signature.getInstance("SHA1withRSA"); sign.initSign(privateKey); sign.update(sourceData); byte[] resultData = sign.sign(); result = Base64.encodeBase64String(resultData); } catch (Exception e) { e.printStackTrace(); } return result; } public static PrivateKey getRSAPrivateKey(String pkcs8_rsa_private_key) { byte[] keyBytes = pkcs8_rsa_private_key.getBytes(); String pem = new String(keyBytes); pem = pem.replace("-----BEGIN PRIVATE KEY-----", ""); pem = pem.replace("-----END PRIVATE KEY-----", ""); pem = pem.replace("\\n", ""); byte[] decoded = Base64.decodeBase64(pem); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded); PrivateKey privateKey = null; try { KeyFactory kf = KeyFactory.getInstance("RSA"); privateKey = kf.generatePrivate(spec); } catch (Exception e) { e.printStackTrace(); } return privateKey; } /** * 公钥验签(A用公钥验签) * @param sign * @param source * @param pkcs8_rsa_public_key * @return */ public static boolean doVerifyBySHA1withRSA(String sign, String source) { byte[] sourceData = source.getBytes(); boolean result = false; try { Signature verify = Signature.getInstance("SHA1withRSA"); verify.initVerify(publicKey); verify.update(sourceData); byte[] decoded = Base64.decodeBase64(sign); result = verify.verify(decoded); } catch (Exception e) { e.printStackTrace(); } return result; } private static PublicKey getRSAPublicKey(String pkcs8_rsa_public_key) { byte[] keyBytes = pkcs8_rsa_public_key.getBytes(); String pem = new String(keyBytes); pem = pem.replace("-----BEGIN PUBLIC KEY-----", ""); pem = pem.replace("-----END PUBLIC KEY-----", ""); pem = pem.replace("\\n", ""); byte[] decoded = Base64.decodeBase64(pem); X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded); PublicKey publicKey = null; try { java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider() ); KeyFactory kf = KeyFactory.getInstance("RSA"); publicKey = kf.generatePublic(spec); } catch (Exception e) { e.printStackTrace(); } return publicKey; } /** * 公钥加密(B用A的公钥加密) * @param plainText * @param pkcs8_rsa_public_key * @return */ public static String doEncryptByRSA(String plainText) { byte[] sourceData = plainText.getBytes(); String result = null; try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] resultData = cipher.doFinal(sourceData); result = Base64.encodeBase64String(resultData); } catch (Exception e) { e.printStackTrace(); } return result; } /** * 私钥解密(A使用私钥解密) * @param encryptedText * @param pkcs8_rsa_private_key * @return */ public static String doDecryptByRSA(String encryptedText) { byte[] sourceData = Base64.decodeBase64(encryptedText); String result = null; try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] resultData = cipher.doFinal(sourceData); result = new String(resultData); } catch (Exception e) { e.printStackTrace(); } return result; } }
3、为配置方便我增加了PemConfig类
public class PemConfig { private String rsa_private_key; private String rsa_public_key; public String getRsa_private_key() { return rsa_private_key; } public void setRsa_private_key(String rsa_private_key) { this.rsa_private_key = rsa_private_key; } public String getRsa_public_key() { return rsa_public_key; } public void setRsa_public_key(String rsa_public_key) { this.rsa_public_key = rsa_public_key; } public PemConfig(String rsa_private_key, String rsa_public_key) { super(); this.rsa_private_key = rsa_private_key; this.rsa_public_key = rsa_public_key; } }
4、main方法测试一下
package com.example.demo.pem; import com.example.demo.constants.Constants; import com.gworld.rsautil.pem.PemConfig; import com.gworld.rsautil.pem.RSAUtil; public class DemoTest { public static void main(String[] args) { String id = "123456789"; PemConfig config = new PemConfig(Constants.A_RSA_PRIVATE_KEY, Constants.A_RSA_PUBLIC_KEY);//读取配置文件的秘钥 RSAUtil.configure(config); String encodeId = RSAUtil.doEncryptByRSA(id); String decodeId = RSAUtil.doDecryptByRSA(encodeId); System.out.println("encodeId="+encodeId); System.out.println("decodeId="+decodeId); String sign = RSAUtil.doSignBySHA1withRSA(id); boolean verify = RSAUtil.doVerifyBySHA1withRSA(sign, id); System.out.println("verify result="+verify); } }
测试结果:
encodeId=EawlyXvRIvL2Ew21wN3YrWgwfEnlPai3ovb1VjmttNXwPPfn6tw5cy9NKpXppUZ6qriQOUF/Ns/oWtwdLjvJE/420tQaq02mfUOnl7oxjvRi/B+j0qET7gnPgtUvssRyniKEwk3UIBUDyeWAacNqCPtwIVEt6KtWr2HKhS8ad0EMYGn/lgRF6fVIrhKfvPFjwTI8xIHK2i2gkMMlInxa2K7ytmHsjaJUrfpvVfZxC3B++jNg/tDw/f3kpSbuqNlcXDNFgbt6EhiiO/3dItwuoePhiz/QrAHu1608LzolS9MpXflTzTYrQ7yVe7JbtmawaspBRGPT4iQy7lbC9YadWg== decodeId=123456789 verify result=true
以上是关于用Java实现RSA加解密及签名和验签——.pem文件格式秘钥的主要内容,如果未能解决你的问题,请参考以下文章