常用的几种非对称加密算法

矫情吗;* 2023-06-10 08:26 385阅读 0赞

文章目录

    • `1、RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)`
    • `2、DSA 签名`

相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。算法代表:RSA,DSA。

RSA 能同时用于加密和数字签名,而DSA只能用于签名,本文重点讲解RSA。

1、RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)

这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。

这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。

RSA 加密工具类:

  1. package com.blog.www.util.coder.asymmetrical;
  2. import com.blog.www.util.coder.base.BaseCoderUtils;
  3. import lombok.extern.slf4j.Slf4j;
  4. import javax.crypto.BadPaddingException;
  5. import javax.crypto.Cipher;
  6. import javax.crypto.IllegalBlockSizeException;
  7. import javax.crypto.NoSuchPaddingException;
  8. import java.io.FileInputStream;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. import java.io.UnsupportedEncodingException;
  12. import java.nio.charset.StandardCharsets;
  13. import java.security.*;
  14. import java.security.cert.CertificateException;
  15. import java.security.interfaces.RSAPrivateKey;
  16. import java.security.interfaces.RSAPublicKey;
  17. import java.security.spec.InvalidKeySpecException;
  18. import java.security.spec.PKCS8EncodedKeySpec;
  19. import java.security.spec.X509EncodedKeySpec;
  20. /** * RSA非对称加密解密工具类 * * <p> * 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。 算法的名字以发明者的名字命名:Ron * Rivest, AdiShamir 和Leonard Adleman。 这种加密算法的特点主要是密钥的变化,RSA同时有两把钥匙,公钥与私钥。 * 同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。 * <p> * 参考: * <br/> * <ul> * <li><a href='https://www.iteye.com/blog/snowolf-381767'>Java加密技术(四)——非对称加密算法RSA</a></li> * <li><a href='https://my.oschina.net/jiangli0502/blog/171263'>RSA加密解密及数字签名Java实现</a></li> * </ul> * <p> * <a href="https://github.com/wwwtyro/cryptico">前端demo<a> <br> * <br> */
  21. @Slf4j
  22. public class RSACoder {
  23. /** * 填充方式。这里有【RSA/ECB/PKCS1Padding】填充(默认)和【RSA/ECB/NoPadding】填充两种可选。 * <p> * 注意:使用填充时,公钥每次加密的字符串都会不一样,这样更安全;不使用则每次都一样。因为java默认是填充的,而安卓默认不填充, * 所以安卓默认加密的密文,java默认不能解密!!必须手动指定他们用一致的填充方式,才能正确加密解密。 */
  24. private static final String CIPHER_MODE = "RSA/ECB/PKCS1Padding";
  25. /** * 算法类型 */
  26. private static final String ALGORITHM = "RSA";
  27. /** * RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024 */
  28. private static final int KEY_SIZE = 1024;
  29. /** * 由公钥字节数组用Base64编码成的字符串,方便传播、储存 */
  30. private static final String PUB_KEY_BASE64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxKRX+P64kA0qrd3JYYZIZ5jam63DsAlx5PKlfC0hOAhJ3wfD2Bjl3CHKNMtEKwcnZlunvikOt7/7uKdVdxDYzwpU2ivwNXDA5kMPsx8prjwS7FsdCMWnOTGWBTCYeReFHWVmSj4KxYaOO7csPWBR0AhQX9qiPSWDEKcnH5YNiiQIDAQAB";
  31. /** * 由私钥字节数组用Base64编码成的字符串,方便传播、储存 */
  32. private static final String PRI_KEY_BASE64 = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALEpFf4/riQDSqt3clhhkhnmNqbrcOwCXHk8qV8LSE4CEnfB8PYGOXcIco0y0QrBydmW6e+KQ63v/u4p1V3ENjPClTaK/A1cMDmQw+zHymuPBLsWx0Ixac5MZYFMJh5F4UdZWZKPgrFho47tyw9YFHQCFBf2qI9JYMQpycflg2KJAgMBAAECgYBltrwc1HzrykQFvDeXTLWwTv+TyFt19UkYhl6L5hNmTkRCI8RvzFUT5XK3ZLSmY2q7lazMTerbo44POU96XVvsV+ltmUW4ohh1cf+q7ICz73r+OEaFdxa+wHFthXvMuKpFbDiH89HfAmGGUVezf7dByClyVxn3yuKlb42ZC6AdsQJBAOyA+mBot7a98txTrMl4jRD1MI9t0dWHA51JzJ2vLBX4IlEr944Qhb6N0lNtYChEkEOCrTlLIDxWUtQhZbTP6R0CQQC/w8PcHulcbCY1JhBTefyzA4jmm9LZ0c+byqCSEiffE6/neTMLOxUpt9zDvtdWw7UvMZWgQ4a8QGZrlCw3Lw9dAkEAg9cqvE/kChU9q6FhszZmvUtR9MLttLD9TNN1I3ohg2W+C64M5L9FL4Lz+toAPrJqEZhpZIUCxWAB8ItlnTRB6QJBAKUMwsv3kxUoRG5kV5LxoK0XMsKBhaZSrmTBrxhqJgUbtb/+Eg/th1aD2LBl1oPoKE75V3Y8CICI0V5whunsSEUCQE1ZvMp5a0yblGENWU5F+kWT3aBCkmMN8Zqp2+R5p8kQ7Chxv7llCZ405YXnTdEQyLp+q6OW+eu0TdIQ3qHkA4c=";
  33. /** * 公钥对象 */
  34. static PublicKey PUB_KEY;
  35. /** * 私钥对象 */
  36. static PrivateKey PRI_KEY;
  37. // 初始化
  38. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  39. // 静态代码块,初始化密钥对象,供后面使用
  40. static {
  41. try {
  42. PUB_KEY = restorePubKey();
  43. PRI_KEY = restorePriKey();
  44. } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
  45. log.error("初始化出错", e);
  46. }
  47. }
  48. /** * 从 .p12 文件中读取私钥。 <br> * <br> * 创建人: leigq <br> * 创建时间: 2017年10月28日 下午4:21:56 <br> * * @param pfxKeyFileName .p12文件路径 * @param aliasName 私钥别名 * @param pfxPassword 私钥密码 * @return 私钥对象 */
  49. public static PrivateKey readP12Key(String pfxKeyFileName, String aliasName, String pfxPassword)
  50. throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException {
  51. InputStream fis = new FileInputStream(pfxKeyFileName);
  52. KeyStore keyStore = KeyStore.getInstance("PKCS12");
  53. keyStore.load(fis, pfxPassword.toCharArray());
  54. return (PrivateKey) keyStore.getKey(aliasName, pfxPassword.toCharArray());
  55. }
  56. // 加密、解密
  57. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  58. /** * 通用加密操作 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午5:37:32 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> * * @param key 公钥或密钥对象 * @param data 明文字符串 * @return 密文字节数组用Base64算法编码成的字符串,方便传输、储存 */
  59. public static String encrypt(Key key, String data)
  60. throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
  61. BadPaddingException {
  62. Cipher cipher = Cipher.getInstance(CIPHER_MODE);
  63. cipher.init(Cipher.ENCRYPT_MODE, key);
  64. byte[] bytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
  65. return BaseCoderUtils.encryptBase64(bytes);
  66. }
  67. /** * 通用解密操作 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午5:43:34 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> * * @param key 公钥或密钥对象 * @param data 密文字符串(由密文字节数组用Base64算法编码成的字符串) * @return 明文字符串 */
  68. public static String decrypt(Key key, String data)
  69. throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException,
  70. IllegalBlockSizeException, BadPaddingException {
  71. Cipher cipher = Cipher.getInstance(CIPHER_MODE);
  72. cipher.init(Cipher.DECRYPT_MODE, key);
  73. byte[] bytes = cipher.doFinal(BaseCoderUtils.decryptBase64(data));
  74. return new String(bytes, StandardCharsets.UTF_8);
  75. }
  76. /** * 用公钥加密 <br> * <br> * 创建人: leigq <br> * 创建时间: 2017年10月24日 下午2:00:49 <br> * * @param decoded 明文字符串 * @return 密文字节数组用Base64算法编码成的字符串,方便传输、储存 */
  77. public static String encryptByPubKey(String decoded)
  78. throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
  79. IllegalBlockSizeException, BadPaddingException {
  80. return encrypt(PUB_KEY, decoded);
  81. }
  82. /** * 用私钥解密 <br> * <br> * 创建人: leigq <br> * 创建时间: 2017年10月24日 下午1:57:42 <br> * * @param encoded 密文字符串(由密文字节数组用Base64算法编码成的字符串) * @return 明文字符串 */
  83. public static String decryptByPriKey(String encoded) throws NoSuchPaddingException, BadPaddingException,
  84. NoSuchAlgorithmException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException {
  85. return decrypt(PRI_KEY, encoded);
  86. }
  87. /** * 用私钥加密 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午5:37:32 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> * * @param decoded 明文字符串 * @return 密文字节数组用Base64算法编码成的字符串,方便传输、储存 */
  88. public static String encryptByPriKey(String decoded)
  89. throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
  90. BadPaddingException {
  91. return encrypt(PRI_KEY, decoded);
  92. }
  93. /** * 用公钥解密 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午5:43:34 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> * * @param encoded 密文字符串(由密文字节数组用Base64算法编码成的字符串) * @return 明文字符串 */
  94. public static String decryptByPubKey(String encoded)
  95. throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException,
  96. IllegalBlockSizeException, BadPaddingException {
  97. return decrypt(PUB_KEY, encoded);
  98. }
  99. /** * 还原公钥,X509EncodedKeySpec 用于构建公钥的规范 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午5:16:50 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> * * @return 公钥对象 */
  100. private static PublicKey restorePubKey()
  101. throws NoSuchAlgorithmException, InvalidKeySpecException {
  102. X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(BaseCoderUtils.decryptBase64(RSACoder.PUB_KEY_BASE64));
  103. KeyFactory factory = KeyFactory.getInstance(ALGORITHM);
  104. return factory.generatePublic(x509EncodedKeySpec);
  105. }
  106. /** * 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午5:19:09 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> * * @return 私钥对象 */
  107. private static PrivateKey restorePriKey()
  108. throws NoSuchAlgorithmException, InvalidKeySpecException {
  109. PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(BaseCoderUtils.decryptBase64(RSACoder.PRI_KEY_BASE64));
  110. KeyFactory factory = KeyFactory.getInstance(ALGORITHM);
  111. return factory.generatePrivate(pkcs8EncodedKeySpec);
  112. }
  113. // 更换密钥对
  114. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  115. /** * 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥 * <p> * 创建人:leigq <br> * 创建时间:2018年8月18日 下午7:35:21 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> */
  116. public static void generateKeyPair() {
  117. try {
  118. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
  119. keyPairGenerator.initialize(KEY_SIZE);
  120. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  121. /* 公钥、私钥用 encryptBase64 还是 encryptBase64Sun 加密都可以,后者的 Base64 是多行的,比较适合保存到文件的方式储存 */
  122. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  123. log.info("新公钥:{}", BaseCoderUtils.encryptBase64(publicKey.getEncoded()));
  124. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  125. log.info("新私钥:{}", BaseCoderUtils.encryptBase64(privateKey.getEncoded()));
  126. } catch (NoSuchAlgorithmException e) {
  127. log.error("生成密钥对异常:", e);
  128. }
  129. }
  130. }

测试加密:

  1. /** * RSA 测试 */
  2. @Slf4j
  3. class RSATest {
  4. public static void main(String[] args) throws IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException,
  5. NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
  6. // 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥
  7. RSACoder.generateKeyPair();
  8. log.warn("公钥加密 >> 私钥解密");
  9. String originalStr = "helloWorld";
  10. log.warn("原文:{}", originalStr);
  11. /* 公钥加密 >> 私钥解密 */
  12. // 公钥加密
  13. String encryptByPubKey = RSACoder.encryptByPubKey(originalStr);
  14. log.warn("公钥加密后:" + encryptByPubKey);
  15. // 私钥解密
  16. String decryptByPriKey = RSACoder.decryptByPriKey(encryptByPubKey);
  17. log.warn("私钥解密后:" + decryptByPriKey);
  18. /* 私钥加密 >> 公钥解密 */
  19. // 私钥加密
  20. String encryptByPriKey = RSACoder.encryptByPriKey(originalStr);
  21. log.warn("私钥加密后:" + encryptByPriKey);
  22. // 公钥解密
  23. String decryptByPubKey = RSACoder.decryptByPubKey(encryptByPriKey);
  24. log.warn("公钥解密后:" + decryptByPubKey);
  25. }
  26. }

RSA加密、解密测试结果:

20191026171006.png

RSA 签名工具类:

  1. package com.blog.www.util.coder.asymmetrical;
  2. import com.blog.www.util.coder.base.BaseCoderUtils;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.apache.commons.codec.DecoderException;
  5. import org.apache.commons.codec.binary.Hex;
  6. import java.nio.charset.StandardCharsets;
  7. import java.security.InvalidKeyException;
  8. import java.security.NoSuchAlgorithmException;
  9. import java.security.Signature;
  10. import java.security.SignatureException;
  11. /** * RSA签名验签类 */
  12. @Slf4j
  13. public class RSASignature extends RSACoder {
  14. /** * 用哪个算法来签名 */
  15. private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
  16. /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 生成签名 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
  17. /** * 用私钥生成 Base64数字签名 * <br> * * @param encoded 加密字符串 * @return 签名,已用Base64编码 */
  18. public static String signToBase64(String encoded) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  19. Signature sign = getSign(encoded.getBytes(StandardCharsets.UTF_8));
  20. return BaseCoderUtils.encryptBase64(sign.sign());
  21. }
  22. /** * 用私钥生成16进制数字签名 * <br> * * @param encoded 加密字符串 * @return 签名,已用转16进制字符串 */
  23. public static String signToHex(String encoded) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  24. Signature sign = getSign(encoded.getBytes(StandardCharsets.UTF_8));
  25. return Hex.encodeHexString(sign.sign());
  26. }
  27. /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 生成签名 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
  28. /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 验证签名 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
  29. /** * 用公钥校验 Base64数字签名 * <br> * * @param encoded 加密数据 * @param signed 签名,已用Base64编码 * @return 校验成功返回true 失败返回false */
  30. public static boolean verifyFromBase64(String encoded, String signed) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  31. Signature verify = getVerify(encoded.getBytes(StandardCharsets.UTF_8));
  32. return verify.verify(BaseCoderUtils.decryptBase64(signed));
  33. }
  34. /** * 用公钥校验 16进制数字签名 * <br> * * @param data 加密数据 * @param signed 签名,是由字节数组转换成的16进制字符串 */
  35. public static boolean verifyFromHex(String data, String signed) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, DecoderException {
  36. Signature verify = getVerify(data.getBytes(StandardCharsets.UTF_8));
  37. return verify.verify(Hex.decodeHex(signed));
  38. }
  39. /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 验证签名 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
  40. /** * 用私钥生成数字签名对象 * <br> * * @param encoded 加密字符串转换的字节数组 * @return Signature,方便进一步转换为其他数据 */
  41. private static Signature getSign(byte[] encoded) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  42. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  43. signature.initSign(PRI_KEY);
  44. signature.update(encoded);
  45. return signature;
  46. }
  47. /** * 用公钥生成校验数字签名对象 * <br> * * @param data 加密字符串转换的字节数组 * @return */
  48. private static Signature getVerify(byte[] data) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  49. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  50. signature.initVerify(PUB_KEY);
  51. signature.update(data);
  52. return signature;
  53. }
  54. }

测试签名:

  1. /** * RSA 签名测试 */
  2. @Slf4j
  3. class RSASignTest {
  4. public static void main(String[] args) throws NoSuchAlgorithmException,
  5. InvalidKeyException, SignatureException, DecoderException {
  6. // 上面公钥加密产生的密文
  7. String ciphertext = "S1E4OieVAlGyrOB7CzKugseg/R9TGSdDhRSna64tTpxJubpndp2AwCrJ3myIoWEqXNBPKlPVo21vd+KQgzhQcX5WxoNXD5sLarmbZ5eFsBNQOuTzwIhSql+zaUKV6qq+RTSYNR4c/fqllh5Mviq73dB42bWbUY7nHlim+jGojPY=";
  8. log.warn("私钥签名——公钥验证签名");
  9. // 产生签名 16 进制签名
  10. String signToBase64 = RSASignature.signToBase64(ciphertext);
  11. log.warn("签名:[{}]", signToBase64);
  12. // 验证签名
  13. boolean verifyFromBase64 = RSASignature.verifyFromBase64(ciphertext, signToBase64);
  14. log.warn("验证签名:[{}]", verifyFromBase64);
  15. // 产生签名 16 进制签名
  16. String signToHex = RSASignature.signToHex(ciphertext);
  17. log.warn("签名:[{}]", signToHex);
  18. // 验证签名
  19. boolean verifyFromHex = RSASignature.verifyFromHex(ciphertext, signToHex);
  20. log.warn("验证签名:[{}]", verifyFromHex);
  21. }
  22. }

测试结果:

20191026171039.png

2、DSA 签名

DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级

具体使用看:https://blog.csdn.net/jianggujin/article/details/53440060

发表评论

表情:
评论列表 (有 0 条评论,385人围观)

还没有评论,来说两句吧...

相关阅读

    相关 加密算法-对称加密&对称加密

    加密算法是一种将明文转换为密文的算法,以保护数据的机密性和安全性。加密算法通常分为两种类型:对称加密算法和非对称加密算法。 1. 对称加密算法:指加密和解密使用相同密钥的算

    相关 对称加密算法

    非对称加密算法和对称加密算法的主要差别在于非对称加密算法用于加密和解密的密匙不同,一个公开称为公钥,一个保密称为私钥;这个算法解决了对称加密的算法的密匙分配的问题,提高了算法的