eclipse實現 RSA數字簽名

RSA數字簽名

**

一、實驗目的

**
學習RSA算法在數字簽名方面的使用,掌握公鑰簽名中最基礎的簽名算法-RSA數字簽名算法的編寫。

二、實驗要求

1. 熟悉RAS基本算法。
2. 熟悉RAS數字簽名算法。
3. 掌握如何使用JavaBigInteger類,簡單實現最基礎的RSA公私鑰簽名算法。

三、開發環境

JDK1.7,Java開發環境(本實驗採用Windows+eclipse作爲實驗環境),要求參與實驗的同學按照對稱加密提供的方法,提前安裝好JDK。
四、實驗內容
【1-1】RAS簽名算法的實現
1.實現公私鑰生成算法:根據書本上的知識, RAS公私鑰生成算法首選需要選取兩個大素數 和 ,並計算 ,進一步計算歐拉函數 。接着隨機選取一個整數 滿足 ,其中, 。最後,計算的 逆元 。因此,簽名私鑰爲 ,公鑰爲 。具體的代碼如下:
public void initKeys() {
BigInteger p = newBigInteger(1024, 500, new Random());
BigInteger q = newBigInteger(1024, 500, new Random());
assert(p.compareTo(q) != 0);
n = p.multiply(q);
BigIntegerfi_n = p.subtract(BigInteger.ONE)
.multiply(q.subtract(BigInteger.ONE));
e = newBigInteger(512, 100, new Random());
d = e.modInverse(fi_n);
System.out.println("n : " + n);
System.out.println("e : " + e);
System.out.println("d : " + d);
}
其中,需要在前面定義 、 和 三個全局變量。
public class RSASignatureAlgorithm {
BigIntegern;
BigIntegere;
BigIntegerd;

2.實現簽名算法:RSA簽名算法是對待簽名的消息 進行簽名,具體簽名的形式如下:

此時, 即爲簽名後的信息。因此,可根據公式,寫代碼如下:
public BigInteger signature(byte m[]) {
BigInteger s = __hash(m).modPow(d, n);
System.out.println("s : " + s);
Return s;
}
而哈希函數的輸出是一個值,其實現可以如下:
public BigInteger __hash(byte m[]) {
MessageDigest md;
try {
md = MessageDigest.getInstance(“SHA-256”);
md.update(m);
byte b[] = newbyte[33];
System.arraycopy(md.digest(), 0, b, 1, 32);
returnnewBigInteger(b);
} catch (NoSuchAlgorithmException e) {
System.out.println(“this cannot happen.”);
}
returnnull;
}
3.實現驗證簽名算法:RSA簽名驗證算法即判定公式 是否成立。因此,代碼的實現可以如下來進行:
public boolean verify(byte m[], BigInteger s) {
BigIntegerleft = __hash(m).mod(n);
BigInteger right = s.modPow(e, n);
returnleft.compareTo(right) == 0;
}
4.實現main方法,在main方法中調用算法進行測試:
publicstaticvoidmain(String args[]) {
RSASignatureAlgorithmrs a = new RSASignatureAlgorithm();
rsa.initKeys();
byte m[] = “My name is XXX-, my students number is XXX.”.getBytes();
BigInteger s = rsa.signature(m);
System.out.println("Real signature verify result : " + rsa.verify(m, s));
s = s.add(BigInteger.ONE);
System.out.println("Faked signature verify result : " + rsa.verify(m, s));
}
【1-2】完整參考代碼

importjava.math.BigInteger;
importjava.security.MessageDigest;
importjava.security.NoSuchAlgorithmException;
importjava.util.Random;


public class RSASignatureAlgorithm {
	BigInteger n;
	BigInteger e;
	BigInteger d;
	
	publicBigInteger __hash(byte m[]) {
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("SHA-256");
			md.update(m);
		byte b[] = newbyte[33];
		System.arraycopy(md.digest(), 0, b, 1, 32);
		return new BigInteger(b);
		} catch (NoSuchAlgorithmException e) {
			System.out.println("this cannot happen.");
		}
	return null;
	}
	
	public void initKeys() {
		BigInteger p = new BigInteger(1024, 500, new Random());
		BigInteger q = new BigInteger(1024, 500, new Random());
		assert(p.compareTo(q) != 0);
		n = p.multiply(q);
		BigIntegerfi_n = p.subtract(BigInteger.ONE)
			.multiply(q.subtract(BigInteger.ONE));
		e = newBigInteger(512, 100, new Random());
		d = e.modInverse(fi_n);
		
		System.out.println("n : " + n);
		System.out.println("e : " + e);
		System.out.println("d : " + d);
	}
	
	public BigInteger signature(byte m[]) {
		BigInteger s = __hash(m).modPow(d, n);
		System.out.println("s : " + s);
		return s;
	}
	
	public boolean verify(byte m[], BigInteger s) {
		BigInteger left  = __hash(m).mod(n);
		BigInteger right = s.modPow(e, n);
		return left.compareTo(right) == 0;
	}
	
	public static void main(String args[]) {
		RSASignatureAlgorithm rsa = new RSASignatureAlgorithm();
		rsa.initKeys();
		byte m[] = "My name is XXX, my students number is XXX.".getBytes();
		BigInteger s = rsa.signature(m);
		System.out.println("Real  signature verify result : " + rsa.verify(m, s));
		s = s.add(BigInteger.ONE);
		System.out.println("Faked signature verify result : " + rsa.verify(m, s));
	}
}


RSA簽名算法是用其生成的私鑰 來對待簽名的消息 進行數據簽名,而用其公鑰 來進行驗證。其中私鑰 是進行祕密保存的,而且只有簽名方纔擁有該私鑰,這就達到了不可否認性。如果兩者用反了,就是RSA的加解密算法,也就是用公鑰 來對消息 進行加密,而用私鑰 來解密。此外,在教科書式學習中可以將隨機數的大小從1024調到512,即可提高運行速度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章