RSA加解密&RSA加验签详解

您所在的位置:网站首页 rsa加密公钥串 RSA加解密&RSA加验签详解

RSA加解密&RSA加验签详解

2024-07-05 20:25:32| 来源: 网络整理| 查看: 265

RSA加解密&RSA加验签详解 RSA 是第一个能同时用于 数据加密 和 数字签名 的算法。签名(认证):私钥签名,公钥/公钥证书验签 加解密:公钥加密 私钥解密

 

 

RSA 加密算法是目前最有影响力的 公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一。RSA 是第一个能同时用于 数据加密 和 数字签名 的算法,它能够 抵抗 到目前为止已知的 所有密码攻击,已被 ISO 推荐为公钥数据加密标准。 1.1 密钥对生成

RSA非对称加密密钥对,可以用OpenSSL的命令生成,也可以直接在线生成(http://web.chacuo.net/netrsakeypair)。

秘钥位数:1024位(bit) 或 2048位(bit) 即,秘钥的长度。在加解密时可能需要分段加解密。1024b和2048b要求的block是不同的。 秘钥格式:PKCS#8格式 pkcs#1格式的也可以转成pkcs#8 证书密码:指的是私钥文件的密码。如果需要加密,可以指定。 无密码的私钥以“-----BEGIN PRIVATE KEY-----”开头,有密码的私钥以“-----BEGIN ENCRYPTED PRIVATE KEY-----”开头。

注意,在线生成的密钥对,是有开头和结尾标记的,并且有换行符。如果直接copy到程序配置里,则要把这些去掉。

1.2 数字证书格式 一般情况,公钥证书采用的是X509的格式,私钥证书采用的是pkcs7/pkcs8/pkcs12的格式。   【1.2.1 公钥证书格式】 格式 扩展名 说明 X.509 PEM格式 .pem .cer .crt Base64编码的ASCII文件,以"-----BEGIN CERTIFICATE-----"开头,以"-----END CERTIFICATE-----"结尾。可存放证书,也可存放私钥。 X.509 DER格式 .der .cer .crt 用于存放证书,它是2进制形式存放的,不含私钥。

 

 

【公钥证书格式英文介绍】

PEM Format The PEM format is the most common format that Certificate Authorities issue certificates in. PEM certificates usually have extentions such as .pem, .crt, .cer, and .key. They are Base64 encoded ASCII files and contain "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" statements. Server certificates, intermediate certificates, and private keys can all be put into the PEM format. Apache and other similar servers use PEM format certificates. Several PEM certificates, and even the private key, can be included in one file, one below the other, but most platforms, such as Apache, expect the certificates and private key to be in separate files. DER Format The DER format is simply a binary form of a certificate instead of the ASCII PEM format. It sometimes has a file extension of .der but it often has a file extension of .cer so the only way to tell the difference between a DER .cer file and a PEM .cer file is to open it in a text editor and look for the BEGIN/END statements. All types of certificates and private keys can be encoded in DER format. DER is typically used with Java platforms. The SSL Converter can only convert certificates to DER format. If you need to convert a private key to DER, please use the OpenSSL commands on this page

 

【1.2.2 私钥证书格式】

格式 扩展名 说明 PKCS#7/P7B格式 .p7b .p7c Base64编码的ASCII文件,以"-----BEGIN PKCS7-----"开头,以"-----END PKCS7-----"结尾。其中,p7b以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。 PKCS#12/PFX格式 .pfx .p12 用于存放个人证书/私钥,他通常包含保护密码,2进制文件。

 

 

【私钥证书格式英文介绍】

PKCS#7/P7B Format The PKCS#7 or P7B format is usually stored in Base64 ASCII format and has a file extention of .p7b or .p7c. P7B certificates contain "-----BEGIN PKCS7-----" and "-----END PKCS7-----" statements. A P7B file only contains certificates and chain certificates, not the private key. Several platforms support P7B files including Microsoft Windows and Java Tomcat. PKCS#12/PFX Format The PKCS#12 or PFX format is a binary format for storing the server certificate, any intermediate certificates, and the private key in one encryptable file. PFX files usually have extensions such as .pfx and .p12. PFX files are typically used on Windows machines to import and export certificates and private keys. When converting a PFX file to PEM format, OpenSSL will put all the certificates and the private key into a single file. You will need to open the file in a text editor and copy each certificate and private key (including the BEGIN/END statments) to its own individual text file and save them as certificate.cer, CACert.cer, and privateKey.key respectively.

 

知道了吧? 再看到.pfx,就可知是pkcs#12格式的私钥证书,.cer就是公钥证书 公钥,可以对外给任何人的加密和解密密码,公开的,可以任何人访问 私钥,私钥是一定要严格保护的,通过私钥可以生成公钥,但是从公钥可以认为是永远无法推导出私钥的。 ∴ pfx文件一般都有文件密码。 pfx→cer   可以用OpenSSL

 

OpenSSL工具可以生成RSA公私钥和证书格式转换。不同格式的证书之间可以做如下转换:

PEM → DER(由私钥证书生成公钥证书)PEM → P7BPEM → PFX

P7B → PEMP7B → PFX

PFX → PEM

DER → PEM(指公钥证书之间的转换)

 

1.2.3 开发语言与私钥证书的关系

开发语言 私钥格式 证书格式 JAVA .key.p8 .crt PHP .key.pem .cert.pem .NET .key.der .crt 其它 .key.pem .cert.pem 我们是java语言,工程propertites配置: #商户私钥 PKCS#8标准的私钥 90000002.mer.prikey.path=cert/90000002.key.p8 #平台公钥 X.509证书(DER格式的二进制文件) plat.cert.path=cert/umpay.cert.crt

 

1.3 RSA在支付api中的使用

下游交易渠道端:持有每个子商户的私钥 和 三方支付平台的公钥

三方支付平台:持有下游渠道的每个子商户的公钥 和 三方平台自己的私钥

 

获取公钥(PublicKey)/私钥(PrivateKey) 2.1 代码 RSACertUtil.java

两种获取Key的方式:1)从证书获取;2)从密钥串获取

package rsademo; import com.umpay.core.util.Base64; import com.umpay.core.util.ProFileUtil; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class RSACertUtils { /** * 读公钥证书文件umpay.cert.crt,得到X509证书 * * @return * @throws Exception */ public static X509Certificate getCert() throws Exception { byte[] b = ProFileUtil.getFileByte("plat.cert.path"); try { ByteArrayInputStream bais = new ByteArrayInputStream(b); CertificateFactory cf = CertificateFactory.getInstance("X.509"); return (X509Certificate) cf.generateCertificate(bais); } catch (CertificateException e) { e.printStackTrace(); } return null; } /** * 从X509公钥证书获取PublicKey * * @return * @throws Exception */ public static PublicKey getPublicKey() throws Exception { X509Certificate x509Certificate = getCert(); try { byte[] keyBytes = x509Certificate.getPublicKey().getEncoded(); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(x509KeySpec); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return null; } /** * 从公钥字符串得到公钥对象 * * @param publicKeyStr * @return */ public static PublicKey getPublicKeyFromKeyString(String publicKeyStr) { try { byte[] keyBytes = Base64.decode(publicKeyStr.getBytes()); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(x509KeySpec); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return null; } /** * 从私钥文件 merId.key.p8 得到私钥对象 * * @param merId * @return */ public static PrivateKey getPrivateKey(String merId) { try { byte[] key = ProFileUtil.getFileByte(merId + ".mer.prikey.path"); PKCS8EncodedKeySpec e = new PKCS8EncodedKeySpec(key); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate(e); } catch (IOException e1) { e1.printStackTrace(); } catch (NoSuchAlgorithmException e1) { e1.printStackTrace(); } catch (InvalidKeySpecException e1) { e1.printStackTrace(); } return null; } /** * 根据私钥字符串得到私钥对象 * * @param privateKeyStr * @return * @throws Exception */ public static PrivateKey getPrivateKeyFromKeyString(String privateKeyStr) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decode(privateKeyStr.getBytes()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey); return keyFactory.generatePrivate(keySpec); } } View Code

 

2.2 java.security下的Key

 

 

2.3 java.security.spec下两个spec

 

 2.3.1 PKCS8EncodedKeySpec * This class represents the ASN.1 encoding of a private key, * encoded according to the ASN.1 type {@code PrivateKeyInfo}. * The {@code PrivateKeyInfo} syntax is defined in the PKCS#8 standard * as follows: * * * PrivateKeyInfo ::= SEQUENCE { * version Version, * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, * privateKey PrivateKey, * attributes [0] IMPLICIT Attributes OPTIONAL } * * Version ::= INTEGER * * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier * * PrivateKey ::= OCTET STRING * * Attributes ::= SET OF Attribute * */ public class PKCS8EncodedKeySpec extends EncodedKeySpec { //class实现代码(略) }

 

2.3.2 X509EncodedKeySpec /** * This class represents the ASN.1 encoding of a public key, * encoded according to the ASN.1 type {@code SubjectPublicKeyInfo}. * The {@code SubjectPublicKeyInfo} syntax is defined in the X.509 * standard as follows: * * * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING } * */ public class X509EncodedKeySpec extends EncodedKeySpec { //class实现代码(略) }

 

【数据加密】RSA加密/RSA解密 3.1 利用公钥加密,利用私钥解密

 

 

 

3.2 RSA加解密代码 RSACipherUtil.java

加解密主要借助于javax.crypto.Cipher来实现 

package rsademo; import com.umpay.core.util.Base64; import javax.crypto.Cipher; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; public class RSACipherUtil { /** * 公钥加密 * * @param data * @return * @throws Exception */ public static String encrypt(PublicKey publicKey, String data, String charset) throws Exception { Cipher cipher = Cipher.getInstance(KeyFactory.getInstance("RSA").getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] cipherText = cipher.doFinal(data.getBytes(charset)); byte[] encodedByte = Base64.encode(cipherText); return new String(encodedByte).replace("\n", ""); } /** * RSA私钥解密 * * @param privateKey * @param data * @return * @throws Exception */ public static String decrypt(PrivateKey privateKey, String data, String charset) throws Exception { byte[] byteData = Base64.decode(data.getBytes(charset)); Cipher cipher = Cipher.getInstance(KeyFactory.getInstance("RSA").getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] retB = cipher.doFinal(byteData); return new String(retB); } } View Code

 

 

 

【数字签名】RSA签名(加签/验签) 

利用私钥签名,利用公钥/公钥证书验签

 4.1 常用的数据签名/验签过程描述

生成rsa签名的过程:

请求实体requestModel → 转换成requestMap → 将map的key进行排序 → 得到签名原串 plainText → 读取properties,根据property读私钥文件或私钥串得到 PrivateKey privateKey → 生成RSA签名 signData= sign(privateKey, plainText)→ Base64编码 → 转换成签名字符串 signature

验签的过程:解析请求报文,得到签名原串 plainText → 从请求头或请求报文里得到签名 signature → Base64解码 signatureData = Base64.decode(signature.getBytes(charset)); → 读取properties,根据公钥证书文件得到X509Certificate 或 公钥串转换成PublicKey → 验签 verifySign(X509Certificate/PublicKey, plainText, signatureData)

 

*base64不是加密算法,但也是SSL经常使用的一种算法,它是编码方式,用来把ascii码和二进制码之间互转。类似的编码方式,还有Hex-16进制编码。

4.2 RSA签名验签代码 RSASignUtil.java package rsademo; import com.umpay.core.util.Base64; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.cert.X509Certificate; public class RSASignUtil { private static final String charset = "UTF-8"; private static final String signType = "spay"; /** * 生成签名 * * @param plainText * @param privateKey * @return */ public static String sign(PrivateKey privateKey, String plainText) { try { Signature signature = getSignatureObj(signType); signature.initSign(privateKey);//public final void initSign(PrivateKey privateKey) signature.update(plainText.getBytes(charset)); byte[] signData = signature.sign(); return new String(Base64.encode(signData)); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } /** * 通过PublicKey来验签 * * @param publicKey * @param plainText * @param signature * @return * @throws Exception */ public static boolean verifySign(PublicKey publicKey, String plainText, String signature) throws Exception { byte[] signData = Base64.decode(signature.getBytes(charset)); try { Signature sig = getSignatureObj(signType); sig.initVerify(publicKey);//public final void initVerify(PublicKey publicKey) sig.update(plainText.getBytes(charset)); return sig.verify(signData); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return false; } /** * 通过公钥X509证书来验签 * * @param cert * @param plainText * @param signature * @return * @throws Exception */ public static boolean verifySign(X509Certificate cert, String plainText, String signature) throws Exception { byte[] signData = Base64.decode(signature.getBytes(charset)); try { Signature sig = getSignatureObj(signType); sig.initVerify(cert);//public final void initVerify(Certificate certificate) sig.update(plainText.getBytes(charset)); return sig.verify(signData); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return false; } private static Signature getSignatureObj(String signType) { String shaAlgorithm = null; if ("rest".equals(signType)) { shaAlgorithm = "SHA256withRSA"; } else if ("spay".equals(signType)) { shaAlgorithm = "SHA1withRSA"; } try { return Signature.getInstance(shaAlgorithm); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } } View Code

 

 

测试 package rsademo; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.UUID; public class TestMain { public static final String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvGGQDrUk7ejBfgR6cwDhTUqDe" + "1+ooXzwowLfRRDqu1N0O9KyeAsY8nI8HUvzYGXODNMBEKZ2v8Ck7lelVoxlgkIAT" + "GHB2nM+TBZOPQAdF0X4crJh1yWjdnrGO5fluqUalwRvYIG91mqIPnvSGL9mLDIhi" + "7PR/duEe7KzwDCi3DQIDAQAB"; public static final String privateKeyString = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK8YZAOtSTt6MF+B" + "HpzAOFNSoN7X6ihfPCjAt9FEOq7U3Q70rJ4CxjycjwdS/NgZc4M0wEQpna/wKTuV" + "6VWjGWCQgBMYcHacz5MFk49AB0XRfhysmHXJaN2esY7l+W6pRqXBG9ggb3Waog+e" + "9IYv2YsMiGLs9H924R7srPAMKLcNAgMBAAECgYEAgzW85QB7K2XyT+87WG23B8GY" + "qcWVRDGxrDxWwyvk6dS73xQ9Mp+TnCIaEHwA25Oe+0iRd8LT1t8alvtNAo6ZWYU9" + "Ek0yuNTJ5YpWIal+A3c25Zm8Ir3CgkCvq7+q+4OOhC4rOMoY6G8rxQQ7fm4noW0A" + "lZbgQJrhaqDfute4v2ECQQDVZZpZgNU7u9E2CoAXUjUMGWmapdyAsfdZo8kq7mP3" + "g/4JdcGVykxP2YTI1rR2/6vPvnRZN8wcSNVRoM+qWTCFAkEA0g0/3m5TD6wR5ajj" + "SoIMmYgu5OFToKVX1mDoPKBnrjsxzuPZHm/KhRtkRzafd+vs/DbLs60QtQTmyY7q" + "BZm26QJBAMq5KgeLF4cWpupS0VrWUuS6o5MxrCdqadPzf6FUNQ2ni8cK4ivdsd9N" + "ghKVvX0q59qEUN2M30+jdVuFjKKE9k0CQBtIHUOGkMM4Vhq+FMdYnMpUJcMUgQgc" + "cYwmigNV0iGPDqkQbuLFIkinhh65uXyZ5+3aMBrmH4VjXZZQOZUAogECQHs7Ywr+" + "ZSMllnuYOM9z+dXCcQRGKfcVa90fGo3bjrqanyhGyjAwwfECajPlTHm75AdgWegH" + "XXWxFu93sms7KJY="; public static void main(String[] args) throws Exception { // testCipher(); testSign(); } public static void testCipher() throws Exception { String text = "abcd" + UUID.randomUUID(); // Key publicKey = RSACertUtils.getPublicKey(); PublicKey publicKey = RSACertUtils.getPublicKeyFromKeyString(TestMain.publicKeyString); String encryptStr = RSACipherUtil.encrypt(publicKey, text, charset); System.out.println("encryptStr:" + encryptStr); // Key privateKey = RSACertUtils.getPrivateKey(merId); PrivateKey privateKey = RSACertUtils.getPrivateKeyFromKeyString(TestMain.privateKeyString); String decryptStr = RSACipherUtil.decrypt(privateKey, encryptStr, charset); System.out.println(decryptStr); System.out.println(text.equals(decryptStr)); } public static void testSign() throws Exception { System.out.println(publicKeyString); String text = "{\"trade_no\":\"1904261100329133\",\"amount\":\"1\",\"mer_id\":\"90000002\",\"mer_date\":\"20190426\",\"order_id\":\"0306262632992608256R\"}"; PrivateKey privateKey = RSACertUtils.getPrivateKeyFromKeyString(privateKeyString); // PrivateKey privateKey = RSACertUtils.getPrivateKey("111"); String signature = RSASignUtil.sign(privateKey, text); System.out.println("signature:" + signature); PublicKey publicKey = RSACertUtils.getPublicKeyFromKeyString(publicKeyString); X509Certificate certificate = RSACertUtils.getCert(); boolean verifiedOK = RSASignUtil.verifySign(publicKey, text, signature); // boolean verifiedOK =RSASignUtil.verifySign(certificate,text,signature); System.out.println(verifiedOK); } }

 

 

常见错误/异常:

1)RSA解密报错 javax.crypto.BadPaddingException: Decryption error

 

2)Base64串的长度是4的倍数,当一个字符串不是有效的base64串时,调用base64.decode方法会返回null。所以,程序要注意NullPointerException。

RSA 一份私钥可以生成多个公钥么?

知乎上也有人问这个问题,>>here

如下的这个私钥与后面的两个公钥都是可以匹配成功的。

正确的理解是,pub1和pub2包含相同的公钥信息,但是它们的格式不同。pub1的格式是pkcs#1,pub2的格式是pkcs#8。 这两种风格的公钥格式之间可以进行相互转换,http://www.metools.info/code/c85.html提供了工具支持。

-----BEGIN RSA PRIVATE KEY----- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJcW0k1wK/1f6l87P6PLhY77soLS120MZ9b9esk4WfqZNH9OkmuwvPCyxPKPSEN9SVrXEMJsBaVQSTNvriOw8qT1YAK6ks46ucTLs24bQ7mODfpReV76bn+4ObwH8oZX0FCYS34Q4huXYjM1hLgZ+WRsJO2RvMxz4Nd62XcgczX7AgMBAAECgYEAgCs47b4pYwB5xp1xSBa/TuMPtND9NKGgeQ2Amq/2DJLoqNJTfY1pSlqsngOUTsQ6dRgaPIP8ahdocXzc4aQawSG7j+moLBnuu8Y3lbxC6jqENlsmc1cmF784UsW/Y1A27crfgzHgcy5BzHXSG5ZyJNHlxmBpqqBit+RuwR2BsTECQQD/pEqwnsYPteVtk7xImcAqBmM+35UWrxXnmBTMRFaCEbcskKOi7FyQe1pD5yF+0dLPtW/CLVYtgKc2Wg59L1UjAkEAl00F1uLqz/idhS8gEx40XI3cLJc55HDnNaUl9afRd6jYtYrVtThEEEbuWS2O1Ks8OIPE+K9fY5+W/TyLp9DFSQJBAO9MOAo6pcYhC+FV0ILZQXNVRWOeYO25+TQwPQ+0zJG2yZNy1Wp1/HPWs/kqC0WuXbrG6RWH4Mp5SozrIfL28qcCQF1f/aCWvo/HQX+2i7cAxxPvwNgMJIBlZWvoFjs7bLzKiaPQoP+MUAUzoVmMEkARxcKjH+bSZK5ZCZgTy6Sv5XECQAuU5/ebdXYdkcJR4H0iOGvIzJ+f/y1KCRQL3giMtf1yefhUgKo0KBv1pGlMaNgnWmFkFoL3z9nKLRt/GEZP4es= -----END RSA PRIVATE KEY-----

【pub1】 -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAJcW0k1wK/1f6l87P6PLhY77soLS120MZ9b9esk4WfqZNH9OkmuwvPCyxPKPSEN9SVrXEMJsBaVQSTNvriOw8qT1YAK6ks46ucTLs24bQ7mODfpReV76bn+4ObwH8oZX0FCYS34Q4huXYjM1hLgZ+WRsJO2RvMxz4Nd62XcgczX7AgMBAAE= -----END RSA PUBLIC KEY----- 【pub2】-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXFtJNcCv9X+pfOz+jy4WO+7KC0tdtDGfW/XrJOFn6mTR/TpJrsLzwssTyj0hDfUla1xDCbAWlUEkzb64jsPKk9WACupLOOrnEy7NuG0O5jg36UXle+m5/uDm8B/KGV9BQmEt+EOIbl2IzNYS4GflkbCTtkbzMc+DXetl3IHM1+wIDAQAB -----END PUBLIC KEY-----

 

 

RSA可以私钥加密吗?

可以。 

通过私钥加密,则解密要通过公钥解密。

通过私钥加密,如果通过私钥解密,就会报异常:

javax.crypto.BadPaddingException: Decryption error at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380) at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291) at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363) at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389) at javax.crypto.Cipher.doFinal(Cipher.java:2165) at com.emax.channel.util.RSAUtils.decryptByPrivateKey(RSAUtils.java:213) at com.emax.channel.provider.TestMain.testRSAEncrypt(TestMain.java:39) View Code

不过,用私钥加密用公钥解密,无法保证数据的安全。用公钥加密用私钥解密,这才能起到加密作用。

因为公钥是公开的,很多人可以持有公钥。若用私钥加密,那所有持有公钥的人都可以进行解密,这是不安全的!若用公钥加密,那只能由私钥解密,而私钥是私有不公开的,只能由特定的私钥持有人解密,保证的数据的安全性。

 

在线验证工具:http://www.metools.info/code/c83.html

 

 

 

当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/11769740.html

posted on 2019-10-31 10:21  buguge  阅读(4341)  评论(0)  编辑  收藏  举报



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭