叙述无保密机制的rsa签名过程_安全系列之——RSA的公钥私钥有多少人能分的清楚?RSA的签名验签与加密解密如何使用公私钥?...
在對接很多的互聯網公司的開發平臺時,這些互聯網公司未來自身平臺的安全,都會需要調用方簽名確認調用方的身份是合法的,同時未來信息網絡傳輸的安全可能還需要加密解密。比如對接支付寶、微信開放平臺時,需要配置公鑰并下載平臺的公鑰,后續調用方就需要對請求的報文進行簽名,支付寶、微信收到請求后需要驗簽,只有身份驗證通過才能執行相關的業務流程。
在實際的開發過程中,有很多人分不清什么是公鑰什么是私鑰,如何進行簽名驗簽及加密解密,以及簽名驗簽與加密解密有什么關系。這一期我們就來詳細說說這個問題。關于RSA的算法請參考我的文章《安全系列之——RSA的前世今生》,加密解密可以參考我的文章《安全系列之——手寫JAVA加密、解密》。
一、公鑰私鑰
在之前的文章《安全系列之——手寫JAVA加密、解密》中,介紹了對稱加密和非對稱加密。其中非對稱加密使用的是RSA算法,所謂的非對稱,指的是,加密時使用的秘鑰和解密時使用的秘鑰是不一樣的。也就是說RSA有一對秘鑰,其中一個是公鑰,另一個是私鑰,一個用于加密,一個用于解密。
RAS算法的兩個應用是簽名驗簽、加密解密。
在網絡通訊過程中,通訊之前,調用方和被調用方都需要生成一對公私鑰;然后調用方和被調用方之間交換公鑰;這樣調用方和被調用方都擁有自己的私鑰和對方的公鑰,這是雙方通訊為了通訊安全就可以做簽名驗簽和加密解密了。
私鑰只能自己擁有,不能暴露給任何人,只要私鑰不暴露,通訊就是安全的。私鑰可以等同于身份。
公鑰可以被任何人獲取。獲取到對方的公鑰,就可以通過公鑰驗證對方的簽名;同時使用對方的公鑰加密,也只能被對方的私鑰解密。
因為公鑰是公開的,也為通訊雙方的公鑰交換提供了便利,不用在考慮交換時是否泄漏了。
二、簽名驗簽與加密解密的關系
首先強調一點,簽名驗簽與加密解密之間沒有關系。
簽名驗簽與加密解密都是為了系統安全而做的必要措施,但是是為了防范不同的安全風險。
簽名驗簽
簽名驗簽:是為了驗證用戶身份是否是合法。比如微信支付,任何合法的商戶都可以調用微信支付接口。那么什么是合法商戶呢?滿足微信的很多要求,比如商戶注冊微信商戶平臺獲得商戶id、簽約相關的支付產品獲得appid、給開通的支付產品配置商戶的公鑰并下載微信的公鑰,這樣的商戶對微信來說才是合法的。然后商戶使用自己的商戶私鑰對相關的請求參數進行簽名后調用微信的支付接口;微信收到請求后通過商戶配置在平臺的商戶公鑰對這個請求進行驗簽,驗簽通過說明這個次請求時一個合法的平臺商戶發起的,驗簽通過后就可以做具體的支付業務了。
簽名為什么用調用方的私鑰?簽名通常是被調用方(平臺)考慮到自身安全要求調用方做簽名,從而驗證調用方是否合法。考慮的是被調用方的安全。因為合法的商戶已經將自己的公鑰配置到微信后臺了,當一個調用者將加簽名的參數傳到微信平臺,而微信平臺恰好能用這個商戶配置的公鑰驗簽通過,說明發請求的人就是持有這個私鑰的合法商戶,因為只有持這個私鑰的商戶才能做出這個簽名,私鑰是保密的,不是每個人都有。如果簽名使用的是公鑰,公鑰人人都可以從網上獲取,一個非法的調用者也可以獲得這個公鑰并簽名向微信發請求,即使微信平臺驗簽通過也不知道這個調用者是否合法。
加密解密
加密解密:是為了防止數據在網絡傳輸中被人劫持。假如商戶調用微信的支付接口時,請求報文中的有很多敏感字段比如銀行卡號、密碼等(實際不需要這些字段),當報文在網絡上傳輸時,被人惡意監聽,就會導致商戶的銀行卡號和密碼泄露,所以商戶在調用時就需要使用微信公鑰對整個報文進行加密;微信收到請求后,就可以使用微信私鑰進行解密,這樣就可以防止敏感信息泄露了。當然https已經在傳輸的時候加密了。
加密為什么用對方的公鑰?加密通常是調用方(商戶)考慮自身安全,保證調用方的敏感信息不被泄露而做的,保證只有真正的被調用方才能解密。如何保證呢?也就是即使信息在網絡傳輸中被劫持了,也不能解密。要想解密,必須持有秘鑰,要想唯一持有秘鑰,那就必須是私鑰,因為私鑰是不對外公開的。能解密,說明這個信息就是發生給他的。所以,信息發給誰,就只能用誰的私鑰才能解密,這就必須要求發送方使用他的公鑰加密了。信息要發給微信平臺,就必須用微信平臺的公鑰加密。
這里簽名驗簽與加密解密使用的是不同的公私鑰。簽名時,站在被調用方(微信平臺)的角度看,微信要求誰調用微信平臺,誰使用自己的私鑰做簽名;解密時,站在調用方(商戶)的角度看,商戶把信息發給誰,誰才能使用自己的私鑰解密。因為私鑰只有自己持有,私鑰可以和合法用戶劃等號。而公鑰是全網公開的,誰都能獲取。
總結:
簽名:A調用B時,B要驗證A是否合法(是否能調用接口),A必須使用自己的私鑰簽名;解密:A調用B時,A要驗證B是否合法(是否能解密),B必須使用自己的私鑰解密;
三、測試
這里模擬A給B發消息的過程,測試前,A生成一對公私鑰,B生成一對公私鑰,然后A和B交互公鑰,A擁有 privateKey_A 和publicKey_B,B擁有privateKey_B和publicKey_A。這里只模擬單向(A請求B)的簽名驗簽和加密解密,有興趣的可以自己模擬雙向的(A請求B,以及B響應A)簽名驗簽和加密解密。
關于公私鑰的生成可以參考之前的文章《安全系列之——手寫JAVA加密、解密》。關注公眾號,輸入關鍵字“java-summary”,即可獲得源碼。
?/*** Description:** @author 諸葛小猿* @date 2020-08-21*/@Slf4jpublic class SignAndEncryptTest {?public static final String SIGN_ALGORITHMS = "SHA1WithRSA";public static final String CHATSET = "utf-8";?public static String publicKey_A = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsnen01CdQc2zh/HihCNNYI6u7AFXf/NrZ/9auPvFsJcK1cWj5EFBU3lrts2OTvrmYVurhABg2g/Ya7glzUt6DwUojHOWtpwFxSH1v7FUJMvxDsbd4GXKRdWqMkqkcCMQYDpGpshbL3IAWYIw6pgnBcKksbzkDrZCZMAyHa1bB3zh5uEm9mcrRlBUGirbPNVt++3ztIfdc4Vp5hbw++daNMFr/VGDohMVg3Dlk4ZktDgHc5nakXkE8hSr6UDTw45JpfZZ0dP9XTi/CSVQdoYD+dsJIZ8uletlbrErRfZEJNx/k0w88P4kfGteNBGhlzzVo45tMkHT33O8QB6JxI4xVQIDAQAB";public static String privateKey_A = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyd6fTUJ1BzbOH8eKEI01gjq7sAVd/82tn/1q4+8WwlwrVxaPkQUFTeWu2zY5O+uZhW6uEAGDaD9hruCXNS3oPBSiMc5a2nAXFIfW/sVQky/EOxt3gZcpF1aoySqRwIxBgOkamyFsvcgBZgjDqmCcFwqSxvOQOtkJkwDIdrVsHfOHm4Sb2ZytGUFQaKts81W377fO0h91zhWnmFvD751o0wWv9UYOiExWDcOWThmS0OAdzmdqReQTyFKvpQNPDjkml9lnR0/1dOL8JJVB2hgP52wkhny6V62VusStF9kQk3H+TTDzw/iR8a140EaGXPNWjjm0yQdPfc7xAHonEjjFVAgMBAAECggEAec/qIPXZIF0CuTuEXKSr38gD5NpVmuPO38EPb0uJ96pgnuCzqMxRhmRN/Qv4ojfmn3UucH7BnJVMJtoeEy39NdtTfeo3aJS963vufNTQlf0NoARk1RElKt1XudPwwQlt2ABu0M/YTV4GlxGhyb3ohKoCN76x+si0MIhurIryovyabZCtlhGD2fg3V1t8RBlCEuz68FtB9fSh4zk7u6RhAL5LCOGNbVAiY4hx/NhrDiBfvQBhJZmPG+3gWjjZFgZEH5B0tGByuG2M+dj2qT5LFepkhGyI/upJwOhJrjiRrvR7LmSYCz0lI8/2fVCF8jN/TJav/1xVR82d/165Movm0QKBgQDZv/H1bhPoCoeh8z3ww8Um5FjFb1MMjmh4oB1d2+0QlYTbSVx6mOxBoh0yk+jKztotJyWs61nnHekOhdHFx9Ij1L8oMxybBK+heTuzl2WIs9/2CRBV4XfKMwNiYxJYkaXxUgeHx/2IVXTuFMKMrWhf7kxk2iFrK+Gv63oY0dmvhwKBgQDR0TWXRXC2qEqH/NV/6d24UHl4i/+UP1aKE9jA8xArJYBlKtTWCgM7g3/wxr0IRB6RocVupop/kZJ9RUFjprfaykDOj+A0oC+IDwUmGIjGbR4P921qjWEVQGIFSJvnIwHwGfEAPxvw0uW2tqz9C2GUZ9OB17lecfIdeJQX2Hb3QwKBgA9bWCclAkZlJ7emPgIS7H6XsCMMfODv0jJfqHKMJiX7RYlpnRoQWukuE70TbWGQQRbaIfAWERsZouwhR/AY7ZsVT/33zNap9/D9adZ6oPCJLwxdC0fjRN1/x4dS0WJpszhXvqw20Iyi6kI4OJhPSoMpfT3HnH/AcoRDqTLC6gVVAoGBAI3f9GfseZHZbERV75wF7HoEWI7tw41f4smNMAUQln9GZXKDKtXsgVEN00ZhbFMZlL4O8GyoyoAGVFLGsLeMdUfJeVbzrLyJEHrlBStEbcAW6rwLJ/5jySDQnzdJaLo7TsUnFXKAOgl24gPRtFmLB5mNN1TWJS86x2esMB+LrK33AoGADEDHIUtulc4zclLH9MJj7JcZPkgVz5llJ1jQj3fOu4iPc9TNvV2gV2kWU446gyMmRrQ2We1awnrjaeSzeFnf0OhL+yTzNUmRLMYWZhja/KMhr7b9vVRCCrysZJod+MWodEH+HIJlu9RGIxv7fNNy1S4yRU92OQU43XQ1S93eaEE=";?public static String publicKey_B = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv8GjRufWGPI7Xe6caZ5h5PbnRIQVzD4P1gDjKZaibcxcApGEaqFkT3Am2U6iKv6paELuwxy+dUL1Jvbs09QljuHgDB9SV0VxSM5LscpCmWJ5P1V6Y/QiholCQHCFR6ok6oE2HWGRw/bPQWr/gHfa2zNPu+CB64cbOxLHIQYIRji47tyywAL5ABhF1msZY2vW8xaFKHGq74sxNpf8s0NUnRnVRANjHtuDa/zvrHim45gqBWg+3gPVSQyPU3ydMoj0AiORJQmqprHaZDB7BufpTEZA6I2WElsKJcsGMdwfSd1s0B1iCzrkMmT30n/XXxyw8qQGsvJvQ2V90QiAV9bV+wIDAQAB";public static String privateKey_B = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/waNG59YY8jtd7pxpnmHk9udEhBXMPg/WAOMplqJtzFwCkYRqoWRPcCbZTqIq/qloQu7DHL51QvUm9uzT1CWO4eAMH1JXRXFIzkuxykKZYnk/VXpj9CKGiUJAcIVHqiTqgTYdYZHD9s9Bav+Ad9rbM0+74IHrhxs7EschBghGOLju3LLAAvkAGEXWaxlja9bzFoUocarvizE2l/yzQ1SdGdVEA2Me24Nr/O+seKbjmCoFaD7eA9VJDI9TfJ0yiPQCI5ElCaqmsdpkMHsG5+lMRkDojZYSWwolywYx3B9J3WzQHWILOuQyZPfSf9dfHLDypAay8m9DZX3RCIBX1tX7AgMBAAECggEBAIkRYyMGCTYfwGvuagPdYOCH1NxXBjXOjwdL7xUFRenyUDrNxbdq0gcuhbaDzMuq6XFLltwFKecsC4zkqHjqhkZSExLXOMaFLur5+4WErIJzr3OkKC5Wjm9YofDp/XsyldzCq+nomodXXuLGFwi/o8NYNEB5xKSVGNPrIkfqxfNazdR63738zq0ZPQmMjxEb/AK5uc+fdF9qosDrNI0SqQng00mhfpilvwHZbOYPfKNfh26lpqTEAGk0gaFGfr/QnhUDAnxfaoLhr9zELr4utrkwpaCzX958MrRB5naeScocYSl1h4Bi6htjjpdLWDKkk/vQ8Keno6GtF9Iha8MdvnECgYEA9p5UzaP3qYek4pe96milqmPiYkQeqSAUWSp1TpC5ppIoyPGMYl7Ia8SOsIYBw+9WL9iIR6jqZOpd/E68j8YsW5PyJuFYQTVjXZrVD76D435mskl4gsKz1izEWz5jzU/oE4mGfuaobfaOuw5ixun7dd8FrXknIVHbne0zyEZ+FY0CgYEAxw0Jq3aJbrJHX8ahPsZAodbWKYH8Ojkt2GkXKdrB9HJ6EGKockjPj7R/+ForXw2XWoGdoL4QPalhKuJX+3bsSQIgt7mDRiDEPK7XkbKd5mS/HTXWXsTIkGaDhYlq6yOkbmRsR3QgCfnhLYaaYkZ6kIKDsGgUJF8oIqxKrlDWo6cCgYBUyulzbu3nLwklE3Er2GElbYRXrv4vviTg53U/1wjN2bEGLe7Ln7UfQIyi6uBOgsrKVpO8t7onimFYL6YrdMKplfuLHK2gdf+9HlAlQqbMIBilMheqNdFpUSkOCix8Wf38QauplBrS/BPlArQ5mhdoVo74LxCiJyfwa68DLCGLvQKBgEGg4tdNtfJxhWbmrrNr2lOB6gq1eNwZjiwUOjbqkZhvRh+w56kGqKjQ8oCH+lTUvlpw8e/VurUZ65egGTIn+6/2q6Ln34h3tTvsydaX9cfI39pZrdyBNT+nDSYyMLZmggiDw8+rUgT4Bm5kOvK8Gh0bax/2sO1tEmacN+NRc/NxAoGALzEnmKI9B46NVNOWi0VLtTdiloSI6bxgli0Rm8T+6wD6y9JNnWsibYydGx9pDn6w2qihuP1QcKruHUiZ7V8aahhD4o4e/a+IgRzNYcQh4CngUzL+XymlqQVbDSaiEiVi/qSNv+i9mgeF/mSYbYcZjhFPjzdOy3hvtO3GtjDSMQw=";?// 封裝發送的消息public static Map<String,String> communicationParams = null;?public static void main(String[] args) {?// A給B發消息ASendMsgToB();?// B接收來自A的消息BReceiveFromA();}??/*** A給B發消息,首先A-B交換公鑰,A擁有 privateKey_A 和 publicKey_B** A使用publicKey_B加密消息,再使用privateKey_A對密文簽名,然后將密文和簽名發給B*/public static void ASendMsgToB(){?// 消息明文String msg = "你好";?// 加密String encryptMsg = encryptByPublicKey(msg,publicKey_B);?// 簽名String sign = signByPrivateKey(encryptMsg,privateKey_A);?// 發送消息communicationParams = new HashMap<String,String>();communicationParams.put("encryptMsg",encryptMsg);communicationParams.put("sign",sign);log.info("A發送給B的消息:{}", JSON.toJSONString(communicationParams));?log.info("-------------------------------------------------");}?/*** B接收A的消息,首先A-B交換公鑰,B擁有 privateKey_B 和 publicKey_A** B收到消息后,先使用publicKey_A驗簽,再使用privateKey_B解密*/public static void BReceiveFromA(){// 接收消息Map<String,String> receiveMsg = communicationParams;log.info("B接收到A的消息:{}", JSON.toJSONString(receiveMsg));String sign = receiveMsg.get("sign");String encryptMsg = receiveMsg.get("encryptMsg");?// 驗簽Boolean tf = verifySignPublicKey(encryptMsg,publicKey_A,sign);if(tf){log.info("驗簽通過,說明這個信息是B認可的用戶發來的");}?// 解密String msg = decryptByPrivateKey(encryptMsg,privateKey_B);log.info("解密成功,說明這個信息就是發給B的");??log.info("B收到的消息:{}", msg);}??/*** RSA簽名* @param content 待簽名數據* @param privateKey 商戶私鑰* @return 簽名值*/public static String signByPrivateKey(String content, String privateKey){try{PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );KeyFactory keyf = KeyFactory.getInstance("RSA");PrivateKey priKey = keyf.generatePrivate(priPKCS8);?Signature signature = Signature.getInstance(SIGN_ALGORITHMS);?signature.initSign(priKey);signature.update( content.getBytes(CHATSET) );?byte[] signed = signature.sign();?return Base64.encode(signed);?}catch (Exception e){log.error(e.getMessage(), e);}?return null;}?/*** RSA驗簽名檢查* @param content 待簽名數據* @param sign 簽名值* @param publicKey 公鑰* @return 布爾值*/public static boolean verifySignPublicKey(String content, String publicKey, String sign){try{KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] encodedKey = Base64.decode(publicKey);PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));?Signature signature = Signature.getInstance(SIGN_ALGORITHMS);?signature.initVerify(pubKey);signature.update( content.getBytes(CHATSET) );?boolean bverify = signature.verify( Base64.decode(sign) );return bverify;?}catch (Exception e){log.error(e.getMessage(), e);}?return false;}?/*** RSA公鑰加密* @param str 加密字符串* @param publicKey 公鑰* @return 密文*/public static String encryptByPublicKey( String str, String publicKey ) {?try{?//base64編碼的公鑰byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(publicKey);RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));?//RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, pubKey);String outStr = org.apache.commons.codec.binary.Base64.encodeBase64String(cipher.doFinal(str.getBytes(CHATSET)));return outStr;?}catch (Exception e) {log.error(e.getMessage(), e);}?return null;}?/*** RSA私鑰解密* @param str 加密字符串* @param privateKey 私鑰* @return 明文*/public static String decryptByPrivateKey(String str, String privateKey){?try{?//64位解碼加密后的字符串byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(str.getBytes(CHATSET));//base64編碼的私鑰byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(privateKey);RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));?//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;?}catch (Exception e) {log.error(e.getMessage(), e);}?return null;}?}?運行結果:
00:09:01.375 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - A發送給B的消息:{"sign":"X13XFI2khSarCOTDjENC/ZTtKfUKAPXuO3b7vossIvC6Aj9WMnKd9w/w64/EqTg+42SGvJXjVpvdglRMmWVrbFSWfmrEfjejaNcq35+aor6j4tMMq0ZVxRO4BxTe+qKDx/e0037dHACvAY2ecojVcbAQaECEc3TrZJguQnte/Nv0DZYPSv/9evPnuKL3DuTl/wy+JaTEhVrvsu/4jXpQ6HRbrhrC4dnzs6AZEqtBXvgfRSkq62jbAvUguDhhZ6yexA2/5S+oOqO8mgRVnooQxkAI5QZd9z0voDIrCDp4emKuznj7vMUjmOXgdD0C3l7LuBqQ469JmAD0U2fRLWMIiQ==","encryptMsg":"lFrlwDA4RjXaxrFPkd8DrbiWQ15o7nNzvLwdWUmTgkDyV5DGMXXsbcEP8aBWqmCje49ymAdzQl3MdO+U2t51QtTvzJOS55EBOZgonN8XJHKNiW7XikWbgf54vUx/mNdHH7fqpBM8AM1qcyH2N3OISFK4NP6eCKgMXRRb3hxw4oko3cGTa98Hnl8jlR9yR2Goy1euT7lpL04VqWcJtP0aEW5gurPkTEDRmOn1UC6x8qZX+K3dxrQfOQhJVRoIOb2hbu/HhzBsknJw1QZTS5IN/n0GlRiJQUwJllQUT4XRF6zmc2y4ewnLwlMY99WqwCaB4XFaBNQO9/5fa7A/XZTr7g=="}00:09:01.378 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - -------------------------------------------------00:09:01.378 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - B接收到A的消息:{"sign":"X13XFI2khSarCOTDjENC/ZTtKfUKAPXuO3b7vossIvC6Aj9WMnKd9w/w64/EqTg+42SGvJXjVpvdglRMmWVrbFSWfmrEfjejaNcq35+aor6j4tMMq0ZVxRO4BxTe+qKDx/e0037dHACvAY2ecojVcbAQaECEc3TrZJguQnte/Nv0DZYPSv/9evPnuKL3DuTl/wy+JaTEhVrvsu/4jXpQ6HRbrhrC4dnzs6AZEqtBXvgfRSkq62jbAvUguDhhZ6yexA2/5S+oOqO8mgRVnooQxkAI5QZd9z0voDIrCDp4emKuznj7vMUjmOXgdD0C3l7LuBqQ469JmAD0U2fRLWMIiQ==","encryptMsg":"lFrlwDA4RjXaxrFPkd8DrbiWQ15o7nNzvLwdWUmTgkDyV5DGMXXsbcEP8aBWqmCje49ymAdzQl3MdO+U2t51QtTvzJOS55EBOZgonN8XJHKNiW7XikWbgf54vUx/mNdHH7fqpBM8AM1qcyH2N3OISFK4NP6eCKgMXRRb3hxw4oko3cGTa98Hnl8jlR9yR2Goy1euT7lpL04VqWcJtP0aEW5gurPkTEDRmOn1UC6x8qZX+K3dxrQfOQhJVRoIOb2hbu/HhzBsknJw1QZTS5IN/n0GlRiJQUwJllQUT4XRF6zmc2y4ewnLwlMY99WqwCaB4XFaBNQO9/5fa7A/XZTr7g=="}00:09:01.379 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - 驗簽通過,說明這個信息是B認可的用戶發來的00:09:01.386 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - 解密成功,說明這個信息就是發給B的00:09:01.386 [main] INFO com.wuxiaolong.EncrypteDecrypt.SignAndEncryptTest - B收到的消息:你好關注公眾號,輸入關鍵字“java-summary”,即可獲得源碼。
完成,收工!
【傳播知識,共享價值】,感謝小伙伴們的關注和支持,我是【諸葛小猿】,一個彷徨中奮斗的互聯網民工!!!
總結
以上是生活随笔為你收集整理的叙述无保密机制的rsa签名过程_安全系列之——RSA的公钥私钥有多少人能分的清楚?RSA的签名验签与加密解密如何使用公私钥?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据丢包怎么修复_交换机发生网络通信故障
- 下一篇: springboot获取原生js请求_七