人人都懂密碼學】一篇最易懂的Java密碼學入門教程(下)

      網友投稿 866 2025-04-04

      【人人都懂密碼學】一篇最易懂的Java密碼學入門教程(下)


      2.4.2 證書從哪里來

      “證書中心”(certificate authority,簡稱CA),為公鑰做認證。證書中心用自己的私鑰,對公鑰和一些相關信息一起加密,生成“數字證書”(Digital Certificate)。

      拿到數字證書以后,就可以放心了。以后只要在簽名的同時,再附上數字證書就行了。

      用CA的公鑰解開數字證書,就可以拿到真實的公鑰了,然后就能證明“數字簽名”是否真的是公司簽的。

      修改之前的RSAdemo代碼:

      /* ?*?Copyright?(c)?Huawei?Technologies?Co.,?Ltd.?2020-2020.?All?rights?reserved. ?*/ package?com.huawei.it.jalor.boot.test; import?com.sun.org.apache.xml.internal.security.utils.Base64; import?org.apache.commons.io.FileUtils; import?javax.crypto.Cipher; import?java.io.File; import?java.nio.charset.Charset; import?java.security.Key; import?java.security.KeyFactory; import?java.security.KeyPair; import?java.security.KeyPairGenerator; import?java.security.PrivateKey; import?java.security.PublicKey; import?java.security.spec.PKCS8EncodedKeySpec; import?java.security.spec.X509EncodedKeySpec; /** ?*?RSAdemo ?* ?*?@Author:?陳志強 ?*?@CreateTime:?2020-10-12 ?*?@Description: ?*/ public?class?RSAdemo?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????String?input?=?"硅谷"; ????????//?加密算法 ????????String?algorithm?=?"RSA"; ????????PrivateKey?privateKey?=?getPrivateKey("a.pri",?algorithm); ????????PublicKey?publicKey?=?getPublicKey("a.pub",?algorithm); ????????String?s?=?encryptRSA(algorithm,?privateKey,?input); ????????String?s1?=?decryptRSA(algorithm,?publicKey,?s); ????????System.out.println(s); ????????System.out.println(s1); ????} ????public?static?PublicKey?getPublicKey(String?pulickPath,String?algorithm)?throws?Exception{ ????????//?將文件內容轉為字符串 ????????String?publicKeyString?=?FileUtils.readFileToString(new?File(pulickPath),?Charset.defaultCharset()); ????????//?獲取密鑰工廠 ????????KeyFactory?keyFactory?=?KeyFactory.getInstance(algorithm); ????????//?構建密鑰規范?進行Base64解碼 ????????X509EncodedKeySpec?spec?=?new?X509EncodedKeySpec(Base64.decode(publicKeyString)); ????????//?生成公鑰 ????????return?keyFactory.generatePublic(spec); ????} ????public?static?PrivateKey?getPrivateKey(String?priPath,String?algorithm)?throws?Exception{ ????????//?將文件內容轉為字符串 ????????String?privateKeyString?=?FileUtils.readFileToString(new?File(priPath),?Charset.defaultCharset()); ????????//?獲取密鑰工廠 ????????KeyFactory?keyFactory?=?KeyFactory.getInstance(algorithm); ????????//?構建密鑰規范?進行Base64解碼 ????????PKCS8EncodedKeySpec?spec?=?new?PKCS8EncodedKeySpec(Base64.decode(privateKeyString)); ????????//?生成私鑰 ????????return?keyFactory.generatePrivate(spec); ????} ????/** ?????*?生成密鑰對并保存在本地文件中 ?????* ?????*?@param?algorithm?:?算法 ?????*?@param?pubPath???:?公鑰保存路徑 ?????*?@param?priPath???:?私鑰保存路徑 ?????*?@throws?Exception ?????*/ ????public?static?void?generateKeyToFile(String?algorithm,?String?pubPath,?String?priPath)?throws?Exception?{ ????????//?獲取密鑰對生成器 ????????KeyPairGenerator?keyPairGenerator?=?KeyPairGenerator.getInstance(algorithm); ????????//?獲取密鑰對 ????????KeyPair?keyPair?=?keyPairGenerator.generateKeyPair(); ????????//?獲取公鑰 ????????PublicKey?publicKey?=?keyPair.getPublic(); ????????//?獲取私鑰 ????????PrivateKey?privateKey?=?keyPair.getPrivate(); ????????//?獲取byte數組 ????????byte[]?publicKeyEncoded?=?publicKey.getEncoded(); ????????byte[]?privateKeyEncoded?=?privateKey.getEncoded(); ????????//?進行Base64編碼 ????????String?publicKeyString?=?Base64.encode(publicKeyEncoded); ????????String?privateKeyString?=?Base64.encode(privateKeyEncoded); ????????//?保存文件 ????????FileUtils.writeStringToFile(new?File(pubPath),?publicKeyString,?Charset.forName("UTF-8")); ????????FileUtils.writeStringToFile(new?File(priPath),?privateKeyString,?Charset.forName("UTF-8")); ????} ????/** ?????*?解密數據 ?????* ?????*?@param?algorithm??????:?算法 ?????*?@param?encrypted??????:?密文 ?????*?@param?key????????????:?密鑰 ?????*?@return?:?原文 ?????*?@throws?Exception ?????*/ ????public?static?String?decryptRSA(String?algorithm,Key?key,String?encrypted)?throws?Exception{ ????????//?創建加密對象 ????????//?參數表示加密算法 ????????Cipher?cipher?=?Cipher.getInstance(algorithm); ????????//?私鑰進行解密 ????????cipher.init(Cipher.DECRYPT_MODE,key); ????????//?由于密文進行了Base64編碼,?在這里需要進行解碼 ????????byte[]?decode?=?Base64.decode(encrypted); ????????//?對密文進行解密,不需要使用base64,因為原文不會亂碼 ????????byte[]?bytes1?=?cipher.doFinal(decode); ????????return?new?String(bytes1); ????} ????/** ?????*?使用密鑰加密數據 ?????* ?????*?@param?algorithm??????:?算法 ?????*?@param?input??????????:?原文 ?????*?@param?key????????????:?密鑰 ?????*?@return?:?密文 ?????*?@throws?Exception ?????*/ ????public?static?String?encryptRSA(String?algorithm,Key?key,String?input)?throws?Exception{ ????????//?創建加密對象 ????????//?參數表示加密算法 ????????Cipher?cipher?=?Cipher.getInstance(algorithm); ????????//?初始化加密 ????????//?第一個參數:加密的模式 ????????//?第二個參數:使用私鑰進行加密 ????????cipher.init(Cipher.ENCRYPT_MODE,key); ????????//?私鑰加密 ????????byte[]?bytes?=?cipher.doFinal(input.getBytes()); ????????//?對密文進行Base64編碼 ????????return?Base64.encode(bytes); ????} ????/** ?????*?從文件中加載公鑰 ?????* ?????*?@param?algorithm?:?算法 ?????*?@param?filePath??:?文件路徑 ?????*?@return?:?公鑰 ?????*?@throws?Exception ?????*/ ????public?static?PublicKey?loadPublicKeyFromFile(String?algorithm,?String?filePath)?throws?Exception?{ ????????//?將文件內容轉為字符串 ????????String?keyString?=?FileUtils.readFileToString(new?File(filePath),?Charset.forName("UTF-8")); ????????return?loadPublicKeyFromString(algorithm,?keyString); ????} ????/** ?????*?從字符串中加載公鑰 ?????* ?????*?@param?algorithm?:?算法 ?????*?@param?keyString?:?公鑰字符串 ?????*?@return?:?公鑰 ?????*?@throws?Exception ?????*/ ????public?static?PublicKey?loadPublicKeyFromString(String?algorithm,?String?keyString)?throws?Exception?{ ????????//?進行Base64解碼 ????????byte[]?decode?=?Base64.decode(keyString); ????????//?獲取密鑰工廠 ????????KeyFactory?keyFactory?=?KeyFactory.getInstance(algorithm); ????????//?構建密鑰規范 ????????X509EncodedKeySpec?keyspec?=?new?X509EncodedKeySpec(decode); ????????//?獲取公鑰 ????????return?keyFactory.generatePublic(keyspec); ????} ????/** ?????*?從文件中加載私鑰 ?????* ?????*?@param?algorithm?:?算法 ?????*?@param?filePath??:?文件路徑 ?????*?@return?:?私鑰 ?????*?@throws?Exception ?????*/ ????public?static?PrivateKey?loadPrivateKeyFromFile(String?algorithm,?String?filePath)?throws?Exception?{ ????????//?將文件內容轉為字符串 ????????String?keyString?=?FileUtils.readFileToString(new?File(filePath),?Charset.forName("UTF-8")); ????????return?loadPrivateKeyFromString(algorithm,?keyString); ????} ????/** ?????*?從字符串中加載私鑰 ?????* ?????*?@param?algorithm?:?算法 ?????*?@param?keyString?:?私鑰字符串 ?????*?@return?:?私鑰 ?????*?@throws?Exception ?????*/ ????public?static?PrivateKey?loadPrivateKeyFromString(String?algorithm,?String?keyString)?throws?Exception?{ ????????//?進行Base64解碼 ????????byte[]?decode?=?Base64.decode(keyString); ????????//?獲取密鑰工廠 ????????KeyFactory?keyFactory?=?KeyFactory.getInstance(algorithm); ????????//?構建密鑰規范 ????????PKCS8EncodedKeySpec?keyspec?=?new?PKCS8EncodedKeySpec(decode); ????????//?生成私鑰 ????????return?keyFactory.generatePrivate(keyspec); ????} } 寫一個驗證數字簽名的類: /* ?*?Copyright?(c)?Huawei?Technologies?Co.,?Ltd.?2020-2020.?All?rights?reserved. ?*/ package?com.huawei.it.jalor.boot.test; import?com.sun.org.apache.xml.internal.security.utils.Base64; import?java.security.PrivateKey; import?java.security.PublicKey; import?java.security.Signature; /** ?*?功能描述:?驗證數字簽名 ?* ?*?@author?cWX970190 ?*?@since?2020-10-11 ?*/ public?class?SignatureDemo?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????String?a?=?"123"; ????????PublicKey?publicKey?=RSAdemo.loadPublicKeyFromFile("RSA",?"a.pub"); ????????PrivateKey?privateKey?=?RSAdemo.loadPrivateKeyFromFile("RSA",?"a.pri"); ????????String?signaturedData?=?getSignature(a,?"sha256withrsa",?privateKey); ????????boolean?b?=?verifySignature(a,?"sha256withrsa",?publicKey,?signaturedData); ????????System.out.println(b); ????} ????/** ?????*?生成簽名 ?????* ?????*?@param?input??????:?原文 ?????*?@param?algorithm??:?算法 ?????*?@param?privateKey?:?私鑰 ?????*?@return?:?簽名 ?????*?@throws?Exception ?????*/ ????private?static?String?getSignature(String?input,?String?algorithm,?PrivateKey?privateKey)?throws?Exception?{ ????????//?獲取簽名對象 ????????Signature?signature?=?Signature.getInstance(algorithm); ????????//?初始化簽名 ????????signature.initSign(privateKey); ????????//?傳入原文 ????????signature.update(input.getBytes()); ????????//?開始簽名 ????????byte[]?sign?=?signature.sign(); ????????//?對簽名數據進行Base64編碼 ????????return?Base64.encode(sign); ????} ????/** ?????*?校驗簽名 ?????* ?????*?@param?input??????????:?原文 ?????*?@param?algorithm??????:?算法 ?????*?@param?publicKey??????:?公鑰 ?????*?@param?signaturedData?:?簽名 ?????*?@return?:?數據是否被篡改 ?????*?@throws?Exception ?????*/ ????private?static?boolean?verifySignature(String?input,?String?algorithm,?PublicKey?publicKey,?String?signaturedData)?throws?Exception?{ ????????//?獲取簽名對象 ????????Signature?signature?=?Signature.getInstance(algorithm); ????????//?初始化簽名 ????????signature.initVerify(publicKey); ????????//?傳入原文 ????????signature.update(input.getBytes()); ????????//?校驗數據 ????????return?signature.verify(Base64.decode(signaturedData)); ????} }

      運行,驗證成功:

      ________________________________________

      拓展: 2.5 Byte和bit

      Byte : 字節. 數據存儲的基本單位,比如移動硬盤1T , 單位是byte

      bit : 比特, 又叫位. 一個位要么是0要么是1. 數據傳輸的單位 , 比如家里的寬帶100MB,下載速度并沒有達到100MB,一般都是12-13MB,那么是因為需要使用 100 / 8

      關系: 1Byte = 8bit

      2.5.1 獲取字符串byte

      /** ?*?ByteBit ?* ?*?@Author:?陳志強 ?*?@CreateTime:?2020-10-12 ?*?@Description: ?*/ public?class?ByteBit?{ ????public?static?void?main(String[]?args)?{ ????????String?a?=?"a"; ????????byte[]?bytes?=?a.getBytes(); ????????for?(byte?b?:?bytes)?{ ????????????int?c=b; ????????????//?打印發現byte實際上就是ascii碼 ????????????System.out.println(c); ????????} ????} }

      運行結果:

      和ascii碼表一致

      2.5.2 byte對應bit

      public?class?ByteBit?{ ????public?static?void?main(String[]?args)?{ ????????String?a?=?"a"; ????????byte[]?bytes?=?a.getBytes(); ????????for?(byte?b?:?bytes)?{ ????????????int?c=b; ????????????//?打印發現byte實際上就是ascii碼 ????????????System.out.println(c); ????????????//?我們在來看看每個byte對應的bit,byte獲取對應的bit ????????????String?s?=?Integer.toBinaryString(c); ????????????System.out.println(s); ????????} ????} }

      運行結果

      2.5.3 中文對應的字節

      package?com.huawei.it.jalor.boot.test; /** ?*?功能描述 ?* ?*?@author?cWX970190 ?*?@since?2020-10-11 ?*/ public?class?ByteBitDemo?{ ????public?static?void?main(String[]?args)?throws?Exception{ ????????String?a?=?"華"; ????????byte[]?bytes?=?a.getBytes(); ????????for?(byte?b?:?bytes)?{ ????????????System.out.print(b?+?"???"); ????????????String?s?=?Integer.toBinaryString(b); ????????????System.out.println(s); ????????} ????} }

      運行程序,我們發現一個中文是有 3 個字節組成:

      我們修改 編碼格式 , 編碼格式改成 GBK

      修改代碼

      //?UTF-8:編碼格式占3個字節 ????????byte[]?bytes?=?a.getBytes("GBK");

      再運行發現變成了 2 個字節

      2.5.4 英文對應的字節

      /** ?*?ByteBit ?* ?*?@Author:?陳志強 ?*?@CreateTime:?2020-10-12 ?*?@Description: ?*/ public?class?ByteBit?{ ????public?static?void?main(String[]?args)?throws?Exception{ ????????String?a?=?"a"; ????????byte[]?bytes?=?a.getBytes(); ????????//?在中文情況下,不同的編碼格式,對應不同的字節 //????????byte[]?bytes?=?a.getBytes("GBK"); ????????for?(byte?b?:?bytes)?{ ????????????System.out.print(b?+?"???"); ????????????String?s?=?Integer.toBinaryString(b); ????????????System.out.println(s); ????????} ????} }

      運行程序

      ________________________________________

      三、如何設置密碼才安全

      通過上述密碼學發展史的介紹,以及對常見加密算法的闡述,相信大家對密碼應該有了較為理性的認識,那么,如何設置密碼才安全呢?這里給出一點小建議:

      密碼不要太常見,不要使用類似于123456式的常用密碼。

      各應用軟件密碼建議不同,避免出現一個應用數據庫被脫庫,全部應用密碼崩塌,

      可在設置密碼時增加注冊時間、注冊地點、應用特性等方法。例如tianjin123456,表示在天津注冊的該應用

      參考文獻:

      現代密碼學之對稱加密-DES及AES算法- element ui

      http://element-ui.cn/article/show-97007.aspx

      Java Base64 編碼與解碼----三種實現方式的代碼實例

      https://blog.csdn.net/qq_27093465/article/details/93977519

      網絡安全之密碼學:信息安全

      https://www.bilibili.com/video/av583369085/

      好了,本期的分享到此就跟大家saygoodbye了,密碼學博大精深,本文只是淺嘗輒止,關于密碼學的知識一直都在更新,希望下次可以給大家帶來更前沿、更實用的密碼學相關知識,喜歡的老鐵歡迎關注,筆芯!

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:我剛才把這PPT做好了 怎末一退出就神魔都沒有了(剛做的ppt)
      下一篇:在視頻教學,想要學習2016版本,但是不知道自己的屬于什么版本
      相關文章
      亚洲精品高清无码视频| 亚洲黄色中文字幕| 久久精品国产亚洲香蕉| 亚洲乱人伦中文字幕无码| 国产亚洲精品自在久久| 亚洲JIZZJIZZ妇女| 91亚洲va在线天线va天堂va国产 | 久久精品夜色国产亚洲av| 国产精品亚洲专区无码WEB| 亚洲欧洲免费视频| 区久久AAA片69亚洲| 亚洲精品无码mⅴ在线观看| 亚洲天天在线日亚洲洲精| 亚洲精品麻豆av| 亚洲一区中文字幕在线电影网| 亚洲成人激情在线| 亚洲国产天堂久久久久久| 亚洲人成无码网站在线观看| 亚洲视频一区调教| 国产AⅤ无码专区亚洲AV| 亚洲AV无码专区国产乱码不卡| 亚洲免费观看在线视频| 日韩亚洲欧洲在线com91tv| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲精品免费观看| 九月婷婷亚洲综合在线| 亚洲午夜国产精品无卡| 亚洲国产午夜精品理论片| 亚洲一区二区三区高清不卡| 亚洲精品成a人在线观看☆| 亚洲成av人片一区二区三区| 中文字幕专区在线亚洲| 亚洲精品国产品国语在线| 水蜜桃亚洲一二三四在线| 亚洲日韩乱码中文无码蜜桃 | 久久水蜜桃亚洲AV无码精品 | 亚洲国产精品狼友中文久久久| 久久亚洲高清综合| 亚洲AV日韩精品久久久久| 亚洲综合久久1区2区3区| 亚洲欧洲日韩国产一区二区三区|