ECDH原理大致了解下
java在ECDH有一个开源的包
bcprov-jdk15on-150.jar 下面有下载地址
我想问知道能不能固定下面的变量 "ecdhkey" 让加密结果也固定
意思也就是说 如果我知道这个"ecdhkey" 能计算出结果吗?
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPublicKeySpec;
import javax.crypto.KeyAgreement;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.math.ec.ECPoint;
import sun.security.ec.NamedCurve;
public class ECDHTest {
* 在控制台打印字节
* @param bArray
* @return
public static final String printBytesToHexString(byte[] bArray) {
String byteStr = bytesToHexString(bArray);
StringBuffer temp = new StringBuffer();
for (int i = 0; i < byteStr.length(); i++) {
if (i != 0 && i % 2 == 0) {
temp.append(" " + byteStr.charAt(i));
} else {
temp.append(byteStr.charAt(i));
return temp.toString();
* 把字节数组转换成16进制字符串
* @param bArray
* @return
public static final String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
return sb.toString();
* 把16进制字符串转换成字节数组
* @param hex
* @return
public static byte[] hexStringToByte(String hex) {
if (hex.length() % 2 != 0) {
hex = "0" + hex;
int len = (hex.length() / 2);
byte[] result = new byte[len];
char[] achar = hex.toCharArray();
for (int i = 0; i < len; i++) {
int pos = i * 2;
result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
return result;
private static byte toByte(char c) {
byte b = (byte) "0123456789ABCDEF".indexOf(c);
return b;
public static void main(String[] args) {
try {
// 711
byte[] serverPBK = new byte[] { 0x04, (byte) 0x92, (byte) 0x8D, (byte) 0x88, 0x50, 0x67, 0x30, (byte) 0x88, (byte) 0xB3, 0x43, 0x26,
0x4E, 0x0C, 0x6B, (byte) 0xAC, (byte) 0xB8, 0x49, 0x6D, 0x69, 0x77, (byte) 0x99, (byte) 0xF3, 0x72, 0x11, (byte) 0xDE,
(byte) 0xB2, 0x5B, (byte) 0xB7, 0x39, 0x06, (byte) 0xCB, 0x08, (byte) 0x9F, (byte) 0xEA, (byte) 0x96, 0x39, (byte) 0xB4,
(byte) 0xE0, 0x26, 0x04, (byte) 0x98, (byte) 0xB5, 0x1A, (byte) 0x99, 0x2D, 0x50, (byte) 0x81, (byte) 0x3D, (byte) 0xA8 };
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
ECParameterSpec ecSpec = NamedCurve.getECParameterSpec("secp192k1");
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", "BC");
SecureRandom sr = new SecureRandom();
// 取消掉这个注释后 结果倒是固定 不过不能得到想要的数据
// sr.setSeed(hexStringToByte("02 D7 2D 3D".replace(" ", "")));
keyGen.initialize(ecSpec, sr); // 公私钥 工厂
KeyPair pair = keyGen.generateKeyPair(); // 生成公私钥
BCECPublicKey cpk = (BCECPublicKey) pair.getPublic();
ECPoint.Fp point = (ECPoint.Fp) cpk.getQ();
System.out.println(pair.getPublic());
// ecdhkey 当我先知道这个 ecdhkey 能不能把已知的值set进去 得到一个固定的结果???
byte[] ecdhkey = point.getEncoded(true);
System.out.println("ecdhkey: " + printBytesToHexString(ecdhkey));
java.security.spec.ECPoint sp = ECPointUtil.decodePoint(ecSpec.getCurve(), serverPBK);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
ECPublicKeySpec pubSpec = new ECPublicKeySpec(sp, ecSpec);
ECPublicKey myECPublicKey = (ECPublicKey) kf.generatePublic(pubSpec);
KeyAgreement agreement = KeyAgreement.getInstance("ECDH", "BC");
agreement.init(pair.getPrivate());
agreement.doPhase(myECPublicKey, true);
System.out.println("secret: " + printBytesToHexString(agreement.generateSecret()));
byte[] xx = agreement.generateSecret();
byte[] result = new byte[16];
// 只需要前面16个字节
System.arraycopy(xx, 0, result, 0, 16);
// 打印最后的密文
System.out.println("result: " + printBytesToHexString(result));
} catch (Exception e) {
e.printStackTrace();
所需jar包下载地址:
http://polydistortion.net/bc/download/bcprov-jdk15on-150.jar