再接再厉,用java实现了PKCS#3 的Diffie-Hellman,这个类比较简单,就不提供下载了,直接粘在下面:
package com.broadthinking.pkcs.pkcs_3;
import java.math.BigInteger;
import java.util.Random;
/**
* This standard describes a method for implementing Diffie-Hellman key
* agreement, whereby two parties, without any prior arrangements, can agree
* upon a secret key that is known only to them (and, in particular, is not
* known to an eavesdropper listening to the dialogue by which the parties agree
* on the key). This secret key can then be used, for example, to encrypt
* further communications between the parties.
*
* @author CaesarZou
*
*/
public class Diffie_Hellman {
private Diffie_Hellman(BigInteger p, BigInteger g, BigInteger x, BigInteger y) {
this.p = p;
this.g = g;
this.x = x;
this.y = y;
}
/**
* Generate a Diffie_Hellman party by input the common args
*
* @param p
* @param g
* @param l
* @return instance of Diffe_Hellman
* @throws PKCS3Exception
*/
public static Diffie_Hellman parameterGeneration(BigInteger p, BigInteger g, int l) throws PKCS3Exception {
BigInteger TWO = BigInteger.valueOf(2);
//A central authority shall select an odd prime p.
if(!p.isProbablePrime(100)) {
throw new PKCS3Exception(PKCS3Exception.ERROR_PARAMTER);
}
//The central authority shall also select an integer g, the base, that satisfies 0 < g < p.
if(!(g.compareTo(BigInteger.ZERO)>0 && g.compareTo(p)<0)) {
throw new PKCS3Exception(PKCS3Exception.ERROR_PARAMTER);
}
//The central authority may optionally select an integer l, the private-value length in bits,
//that satisfies 2^(l-1) <= p.
BigInteger bl = null;
if(l>0) {
bl = TWO.pow(l-1);
if(bl.compareTo(p)>0) {
throw new PKCS3Exception(PKCS3Exception.ERROR_PARAMTER);
}
}
//The length of the prime p in octets is the integer k satisfying2^8(k−1) <= p < 2^8k .
//7.1 Private-value generation
//An integer x, the private value, shall be generated privately and randomly.
//This integer shall satisfy 0 < x < p−1,
BigInteger leftExtent = BigInteger.ZERO;
BigInteger rightExtent = p.subtract(BigInteger.ONE);
if(l>0) {
//unless the central authority specifies a private- value length l,
//in which case the integer shall satisfy 2l-1 ≤ x < 2l.
leftExtent = bl;
BigInteger rightExtent2 = TWO.pow(l);
if(rightExtent2.compareTo(rightExtent)<0) {
rightExtent = rightExtent2;
}
}
//to make a random x between leftExtent and rightExtent
//let range = (rightExtend-leftExtend)
//let x = leftExtend + random(range.length)%range
BigInteger range = rightExtent.subtract(leftExtent);
BigInteger x = new BigInteger(range.bitLength(),new Random());
x = x.mod(range);
x = x.add(leftExtent);
//7.2 Exponentiation
//The base g shall be raised to the private value x modulo p to give an integer y,
//the integer public value.
//y = g^x mod p, 0 < y < p .
//This is the classic discrete-exponentiation computation
BigInteger y = g.modPow(x, p);
return new Diffie_Hellman(p,g,x,y);
}
/**
* get public value
* @return
*/
public BigInteger getY() {
return this.y;
}
/**
* calc secret key by other party's public value
* @param y
* @return z
*/
public BigInteger getZ(BigInteger y) {
/*
* z = (y')x mod p, 0 < z < p .
*/
return y.modPow(this.x, this.p);
}
//
BigInteger x;
BigInteger y;
BigInteger p;
BigInteger g;
}
package com.broadthinking.pkcs.pkcs_3.test;
import java.math.BigInteger;
import com.broadthinking.pkcs.pkcs_3.Diffie_Hellman;
import com.broadthinking.pkcs.pkcs_3.PKCS3Exception;
public class TestVect {
public static void main(String [] args) throws PKCS3Exception {
BigInteger p = new BigInteger(new byte [] {
(byte)0x00,
(byte)0xee, (byte)0xcf, (byte)0xae, (byte)0x81, (byte)0xb1, (byte)0xb9, (byte)0xb3, (byte)0xc9, (byte)0x08, (byte)0x81, (byte)0x0b, (byte)0x10, (byte)0xa1, (byte)0xb5, (byte)0x60, (byte)0x01,
(byte)0x99, (byte)0xeb, (byte)0x9f, (byte)0x44, (byte)0xae, (byte)0xf4, (byte)0xfd, (byte)0xa4, (byte)0x93, (byte)0xb8, (byte)0x1a, (byte)0x9e, (byte)0x3d, (byte)0x84, (byte)0xf6, (byte)0x32,
(byte)0x12, (byte)0x4e, (byte)0xf0, (byte)0x23, (byte)0x6e, (byte)0x5d, (byte)0x1e, (byte)0x3b, (byte)0x7e, (byte)0x28, (byte)0xfa, (byte)0xe7, (byte)0xaa, (byte)0x04, (byte)0x0a, (byte)0x2d,
(byte)0x5b, (byte)0x25, (byte)0x21, (byte)0x76, (byte)0x45, (byte)0x9d, (byte)0x1f, (byte)0x39, (byte)0x75, (byte)0x41, (byte)0xba, (byte)0x2a, (byte)0x58, (byte)0xfb, (byte)0x65, (byte)0x99
});
BigInteger g = new BigInteger(new byte [] {
(byte)0x00,
(byte)0xb0, (byte)0x6c, (byte)0x4f, (byte)0xda, (byte)0xbb, (byte)0x63, (byte)0x01, (byte)0x19, (byte)0x8d, (byte)0x26, (byte)0x5b, (byte)0xdb, (byte)0xae, (byte)0x94, (byte)0x23, (byte)0xb3,
(byte)0x80, (byte)0xf2, (byte)0x71, (byte)0xf7, (byte)0x34, (byte)0x53, (byte)0x88, (byte)0x50, (byte)0x93, (byte)0x07, (byte)0x7f, (byte)0xcd, (byte)0x39, (byte)0xe2, (byte)0x11, (byte)0x9f,
(byte)0xc9, (byte)0x86, (byte)0x32, (byte)0x15, (byte)0x4f, (byte)0x58, (byte)0x83, (byte)0xb1, (byte)0x67, (byte)0xa9, (byte)0x67, (byte)0xbf, (byte)0x40, (byte)0x2b, (byte)0x4e, (byte)0x9e,
(byte)0x2e, (byte)0x0f, (byte)0x96, (byte)0x56, (byte)0xe6, (byte)0x98, (byte)0xea, (byte)0x36, (byte)0x66, (byte)0xed, (byte)0xfb, (byte)0x25, (byte)0x79, (byte)0x80, (byte)0x39, (byte)0xf7
});
//test two part use same p,g without l limit
{
Diffie_Hellman part1 = Diffie_Hellman.parameterGeneration(p, g, -1);
Diffie_Hellman part2 = Diffie_Hellman.parameterGeneration(p, g, -1);
BigInteger z1 = part1.getZ(part2.getY());
BigInteger z2 = part2.getZ(part1.getY());
if(z1.compareTo(z2)==0) {
System.out.println("success!");
}else {
System.out.println("error!");
}
}
//test two part use same p,g with l limit
{
Diffie_Hellman part1 = Diffie_Hellman.parameterGeneration(p, g, 500);
Diffie_Hellman part2 = Diffie_Hellman.parameterGeneration(p, g, 500);
BigInteger z1 = part1.getZ(part2.getY());
BigInteger z2 = part2.getZ(part1.getY());
if(z1.compareTo(z2)==0) {
System.out.println("success!");
}else {
System.out.println("error!");
}
}
}
}