一個基於RSA演算法的Java數位簽章例子

來源:互聯網
上載者:User
一個基於RSA演算法的Java數位簽章例子
潤名,Monday, Fifth Of June 2006  

一、前言:

  網路資料安全性組件括資料的本身的安全性、資料的完整性(防止篡改)、資料來源的不可否認性等要素。對資料採用密碼編譯演算法加密可以保證資料本身的安全性,利用訊息摘要可以保證資料的完整性,但是還有一點就是資料來源的不可否認性(也就是資料來自哪裡接收者是清楚的,而且發送資料者不可抵賴)。
      

       有些方案曾經使用訊息認證碼(MAC)來保證資料來源於合法的發送著,但是利用訊息認證碼會帶來一個問題,就是通訊雙方必須事先約定兩者之間的通訊用共用密碼。在我們的互連網如此龐大的今天,這顯然是不合適的,而數位簽章可以解決我們的這個問題。數位簽章(通常的數位簽章)的基礎是公開金鑰密碼體系(例如:RSA)。寄件者有獨一無二的公開金鑰和私密金鑰,公開金鑰是公開的,私密金鑰秘密保留。寄件者利用私密金鑰對資料的訊息摘要進行數位簽章,接收者利用寄件者的公開金鑰來驗證數位簽章,其實就是把加密過程顛倒過來使用。由於寄件者的私密金鑰是獨一無二的,而且是秘密的,因此當能夠驗證解開數位簽章的數字摘要是正確的後,那麼我們就可以肯定寄件者的身份了,這就是數位簽章的基本原理。

       為什麼要用訊息摘要呢?原因是這樣的,由於公開金鑰加密演算法加解密的速度較慢,對整個資料進行加密肯定是行不通的,而訊息摘要有個好處就是短而且長度固定,就象資料的指紋一樣,所以對摘要進行簽名。

二、數字簽字的原理:

       在數位簽章應用中,首先由寄件者身份產生它的私密金鑰和公開金鑰,然後由寄件者通過私密金鑰把資料加密後,並將加密後的資料發送給接收者;接收者把寄件者加密過的資料通過寄件者的共鑰進行簽名驗證。

三、例子說明:

       現在我們就轉入正題了。JAVA的數位簽章類封裝在Signature類(java.security.Signature)中。
接下來,我會編寫三個功能(即三個Java類):
      a、產生一對密鑰,即私密金鑰和公開金鑰,對於密鑰的儲存可以使用物件流程的方式進行儲存和傳送,也可以使用編碼的方式儲存;在這裡基於方便,我是使用編碼方式進行儲存的;類名是:GenerateKeyPair.java

      b、編寫寄件者的功能:首先通過私密金鑰加密待輸出資料Data,並輸出Data和簽名後的Data;類名是:SignatureData.java
      
     c、編寫接收者的功能:使用寄件者的公開金鑰來驗證發送過來的加密Data,判斷簽名的合法性;類名是:VerifySignature.java

四、產生一對密鑰,即私密金鑰和公開金鑰,對於密鑰的儲存可以使用物件流程的方式進行儲存和傳送,也可以使用編碼的方式儲存;在這裡基於方便,我是使用編碼方式進行儲存的;類名是:GenerateKeyPair.java

package com._21cn.cryptto;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;

public class GenerateKeyPair {

private String priKey;
private String pubKey;
public void run() {
try {
java.security.KeyPairGenerator keygen = java.security.KeyPairGenerator
.getInstance("RSA");
SecureRandom secrand = new SecureRandom();
secrand.setSeed("21cn".getBytes()); // 初始化隨機產生器
keygen.initialize(1024, secrand);
KeyPair keys = keygen.genKeyPair();

PublicKey pubkey = keys.getPublic();
PrivateKey prikey = keys.getPrivate();

pubKey = bytesToHexStr(pubkey.getEncoded());

priKey = bytesToHexStr(prikey.getEncoded());

System.out.println("pubKey=" + pubKey);
System.out.println("priKey=" + priKey);

System.out.println("寫入對象 pubkeys ok");
System.out.println("產生金鑰組成功");
} catch (java.lang.Exception e) {
e.printStackTrace();
System.out.println("產生金鑰組失敗");
}
;

}

/**
* Transform the specified byte into a Hex String form.
*/
public static final String bytesToHexStr(byte[] bcd) {
StringBuffer s = new StringBuffer(bcd.length * 2);

for (int i = 0; i < bcd.length; i++) {
s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);
s.append(bcdLookup[bcd[i] & 0x0f]);
}

return s.toString();
}

/**
* Transform the specified Hex String into a byte array.
*/
public static final byte[] hexStrToBytes(String s) {
byte[] bytes;

bytes = new byte[s.length() / 2];

for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
16);
}

return bytes;
}

private static final char[] bcdLookup = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GenerateKeyPair n = new GenerateKeyPair();
n.run();
}

      

五、編寫寄件者的功能:首先通過私密金鑰加密待輸出資料Data,並輸出Data和簽名後的Data;類名是:SignatureData.java

package com._21cn.cryptto;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

public class SignatureData {

public void run() {
try {

String prikeyvalue = "30820277020100300d";//這是GenerateKeyPair輸出的私密金鑰編碼
PKCS8EncodedKeySpec priPKCS8=new PKCS8EncodedKeySpec(hexStrToBytes(prikeyvalue));
KeyFactory keyf=KeyFactory.getInstance("RSA");
PrivateKey myprikey=keyf.generatePrivate(priPKCS8);

String myinfo = "orderId=10dkfadsfksdkssdkd&amount=80&orderTime=20060509"; // 要簽名的資訊
// 用私密金鑰對資訊產生數位簽章
java.security.Signature signet = java.security.Signature
.getInstance("MD5withRSA");
signet.initSign(myprikey);
signet.update(myinfo.getBytes("ISO-8859-1"));
byte[] signed = signet.sign(); // 對資訊的數位簽章

System.out.println("signed(簽名內容)原值=" + bytesToHexStr(signed));
System.out.println("info(原值)=" + myinfo);

System.out.println("簽名並組建檔案成功");
} catch (java.lang.Exception e) {
e.printStackTrace();
System.out.println("簽名並組建檔案失敗");
}
;

}
/**
* Transform the specified byte into a Hex String form.
*/
public static final String bytesToHexStr(byte[] bcd) {
StringBuffer s = new StringBuffer(bcd.length * 2);

for (int i = 0; i < bcd.length; i++) {
s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);
s.append(bcdLookup[bcd[i] & 0x0f]);
}

return s.toString();
}

/**
* Transform the specified Hex String into a byte array.
*/
public static final byte[] hexStrToBytes(String s) {
byte[] bytes;

bytes = new byte[s.length() / 2];

for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
16);
}

return bytes;
}

private static final char[] bcdLookup = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SignatureData s = new SignatureData();
s.run();

}

   

六、編寫接收者的功能:使用寄件者的公開金鑰來驗證發送過來的加密Data,判斷簽名的合法性;類名是:VerifySignature.java

package com._21cn.cryptto;

import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

public class VerifySignature {

public void run1() {
try {
String pubkeyvalue = "30819f300d06092a864886f70d01010105";//這是GenerateKeyPair輸出的公開金鑰編碼
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(hexStrToBytes(pubkeyvalue));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(bobPubKeySpec);

String info = "orderId=10dkfadsfksdkssdkd&amount=80&orderTime=20060519";
byte[] signed = hexStrToBytes("2292e02ba6bf6f1b1688a6fa2");//這是SignatureData輸出的數位簽章
java.security.Signature signetcheck=java.security.Signature.getInstance("MD5withRSA");
signetcheck.initVerify(pubKey);
signetcheck.update(info.getBytes());
if (signetcheck.verify(signed)) {
System.out.println("info=" + info);
System.out.println("簽名正常");
}
else System.out.println("非簽名正常");
}
catch (java.lang.Exception e) {e.printStackTrace();}

}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.