第十四章 數位簽章演算法--RSA,數位簽章--rsa

來源:互聯網
上載者:User

第十四章 數位簽章演算法--RSA,數位簽章--rsa

注意:本節內容主要參考自

  • 《Java加密與解密的藝術(第2版)》第9章“帶密鑰的訊息摘要演算法--數位簽章演算法”
  • 《大型分布式網站架構(設計與實踐)》第3章“互連網安全架構”

14.1、數位簽章演算法

特點:

  • 非對稱式加密演算法+訊息摘要演算法的結合體
  • 抗否認性、認證資料來源、防止資料被篡改(具體意思與做法查看下邊的過程與類比部分)
  • 私密金鑰加密(簽名)、公開金鑰解密(驗證)

過程:

1)訊息寄件者產生一個金鑰組(私密金鑰+公開金鑰),然後將公開金鑰發送給訊息接收者

2)訊息寄件者使用訊息摘要演算法對原文進行加密(加密後的密文稱作摘要)

3)訊息寄件者將上述的摘要使用私密金鑰加密得到密文--這個過程就被稱作簽名處理,得到的密文就被稱作簽名(注意,這個簽名是名詞)

4)訊息寄件者將原文與密文發給訊息接收者

5)訊息接收者使用公開金鑰對密文(即簽名)進行解密,得到摘要值content1

6)訊息接收者使用與訊息寄件者相同的訊息摘要演算法對原文進行加密,得到摘要值content2

7)比較content1是不是與content2相等,若相等,則說明訊息沒有被篡改(訊息完整性),也說明訊息卻是來源於上述的訊息發送方(因為其他人是無法偽造簽名的,這就完成了“抗否認性”和“認證訊息來源”)

類比:

手寫簽名:

  • 張三在合約上籤了自己的名字,這樣張三在後來想否認自己的這個合約內容時,就不行了(抗否認性)
  • 在張三簽過名之後,若合約內容又發生了變化,這個時候簽名就可以看做無效了
  • 當然,我們通過合約上張三的簽名,我們就可以知道簽名的來源是張三(認證資料來源)

常見的數位簽章演算法:

  • RSA(數位簽章演算法的經典,也是最常用的數位簽章演算法)
  • DSA(是後續數位簽章演算法的基礎)
  • ECDSA(ECC+DSA的結合體,相較於其他數位簽章演算法,速度快,強度高,簽名短,但是使用還沒有RSA廣泛)

14.2、RSA

常見演算法:

  • MD5WithRSA(JDK6)
  • SHA1WithRSA(JDK6)
  • SHA256WithRSA(>=JDK1.6.45,Bouncy Castle-->簡稱BC)

注意:在《Java加密與解密(第二版)》一書中,說JDK6不支援SHA256WithRSA,但是經過我自己測試1.6.45是支援的。

實現方式:(參考上邊三行)

  • JDK
  • BC

14.2.1、基於JDK6實現的MD5WithRSA或SHA1WithRSA或SHA256WithRSA演算法

1 package com.uti.rsa.digital; 2 3 import java.io.UnsupportedEncodingException; 4 import java.security.InvalidKeyException; 5 import java.security.KeyFactory; 6 import java.security.KeyPair; 7 import java.security.KeyPairGenerator; 8 import java.security.NoSuchAlgorithmException; 9 import java.security.PrivateKey; 10 import java.security.PublicKey; 11 import java.security.Signature; 12 import java.security.SignatureException; 13 import java.security.spec.InvalidKeySpecException; 14 import java.security.spec.PKCS8EncodedKeySpec; 15 import java.security.spec.X509EncodedKeySpec; 16 17 import org.apache.commons.codec.binary.Base64; 18 19 /** 20 * 基於BC的RSA數位簽章演算法 21 */ 22 public class RSACoderBC { 23 private static final String ENCODING = "UTF-8"; 24 private static final String KEY_ALGORITHM = "RSA";//非對稱式加密密鑰演算法 25 private static final String SIGNATURE_ALGORITHM = "MD5withRSA";//指定數位簽章演算法(可以換成SHA1withRSA或SHA256withRSA) 26 private static final int KEY_SIZE = 512;//非對稱金鑰長度(512~1024之間的64的整數倍) 27 28 /** 29 * 產生發送方金鑰組 30 */ 31 public static KeyPair initKey() throws NoSuchAlgorithmException{ 32 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);//金鑰組產生器 33 keyPairGenerator.initialize(KEY_SIZE);//指定密鑰長度 34 KeyPair keyPair = keyPairGenerator.generateKeyPair();//產生金鑰組 35 return keyPair; 36 } 37 38 /** 39 * 還原公開金鑰 40 * @param pubKey 二進位公開金鑰 41 */ 42 public static PublicKey toPublicKey(byte[] pubKey) throws NoSuchAlgorithmException, 43 InvalidKeySpecException{ 44 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//密鑰工廠 45 return keyFactory.generatePublic(new X509EncodedKeySpec(pubKey));//還原公開金鑰 46 } 47 48 /** 49 * 還原私密金鑰 50 * @param priKey 二進位私密金鑰 51 */ 52 public static PrivateKey toPrivateKey(byte[] priKey) throws NoSuchAlgorithmException, 53 InvalidKeySpecException{ 54 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//密鑰工廠 55 return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(priKey));//還原私密金鑰 56 } 57 58 /** 59 * 私密金鑰加密(簽名) 60 * @param data 待加密資料 61 * @param keyByte 私密金鑰 62 */ 63 public static byte[] encryptPriKey(String data, byte[] keyByte) throws NoSuchAlgorithmException, 64 InvalidKeySpecException, 65 InvalidKeyException, 66 SignatureException, 67 UnsupportedEncodingException { 68 PrivateKey priKey = toPrivateKey(keyByte);//還原私密金鑰 69 70 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 71 signature.initSign(priKey); 72 signature.update(data.getBytes(ENCODING)); 73 74 return signature.sign(); 75 } 76 77 /** 78 * 公開金鑰解密(驗證) 79 * @param data 原文(待加密資料,也成為“待校正資料”) 80 * @param keyByte 公開金鑰 81 * @param sign 密文(也稱作“簽名”) 82 */ 83 public static boolean decryptPubKey(String data, byte[] keyByte, byte[] sign) throws NoSuchAlgorithmException, 84 InvalidKeySpecException, 85 InvalidKeyException, 86 SignatureException, 87 UnsupportedEncodingException { 88 PublicKey pubKey = toPublicKey(keyByte);//還原公開金鑰 89 90 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 91 signature.initVerify(pubKey); 92 signature.update(data.getBytes(ENCODING)); 93 94 return signature.verify(sign); 95 } 96 97 /** 98 * 擷取公開金鑰 99 */100 public static byte[] getPublicKey(KeyPair keyPair){101 return keyPair.getPublic().getEncoded();102 }103 104 /**105 * 擷取私密金鑰106 */107 public static byte[] getPrivateKey(KeyPair keyPair){108 return keyPair.getPrivate().getEncoded();109 }110 111 /**112 * 測試113 */114 public static void main(String[] args) throws NoSuchAlgorithmException, 115 InvalidKeyException, 116 InvalidKeySpecException, 117 SignatureException, 118 UnsupportedEncodingException {119 byte[] pubKey1;//甲方公開金鑰120 byte[] priKey1;//甲方私密金鑰121 122 /*********************測試是否可以正確產生以上2個key*********************/123 KeyPair keyPair1 = RSACoderBC.initKey();//產生甲方金鑰組124 pubKey1 = RSACoderBC.getPublicKey(keyPair1);125 priKey1 = RSACoderBC.getPrivateKey(keyPair1);126 127 System.out.println("甲方公開金鑰pubKey1-->"+Base64.encodeBase64String(pubKey1)+"@@pubKey1.length-->"+pubKey1.length);128 System.out.println("甲方私密金鑰priKey1-->"+Base64.encodeBase64String(priKey1)+"@@priKey1.length-->"+priKey1.length);129 130 /*********************測試甲方使用私密金鑰加密資料向乙方發送,乙方使用公開金鑰解密資料*********************/131 System.out.println("甲方-->乙方");132 String data = "找一個好姑娘啊!你好嗎,孩子";133 byte[] encodeStr = RSACoderBC.encryptPriKey(data, priKey1);//加密(簽名)134 System.out.println("甲方加密後的資料-->"+Base64.encodeBase64String(encodeStr)+"@@encodeStr.length-->"+encodeStr.length);135 boolean decodeStr = RSACoderBC.decryptPubKey(data, pubKey1, encodeStr);136 System.out.println("乙方檢驗結果-->"+decodeStr);137 }138 }View Code

注意點:

  • 代碼與RSA非對稱式加密演算法(查看第十二章)基本一樣,只是將其中的私密金鑰加密與公開金鑰解密部分的加解密演算法改為簽名和驗證演算法,當然沒有“公開金鑰加密,私密金鑰解密”

疑問:在《Java加密與解密的藝術(第二版)》一書中,作者說:“RSA數位簽章演算法的簽名值與密鑰長度相同”,但是在我的測試中,結果不一致:

1)在我配置非對稱金鑰為512的時候,測出來的公開金鑰長度是96位,私密金鑰長度是345位,與512差很遠,那這裡的512到底是怎麼計算的?

2)訊息摘要的結果長度是64(摘要值的二進位自己數組長度),不知道到底是怎麼與密鑰長度相同的?

以上兩個問題,有知道的朋友請指點一下,謝謝!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.