再接再厉,用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!"); } } } }