PKCS#3 v1.4 java 語言實現參考

鄒德強發表於2012-03-28

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




相關文章