java如何将从DiffieHellman类生成的AES密钥添加到使用该密钥的类
背景:我有两台通过IP/端口连接进行通信的设备,通过Diffie-Hellman密钥交换建立实时语音加密通信,并通过AES算法进行加密。现在已经编写了一些代码,其中一些只是作为原型实现的示例
问题:现在,即使理解我的类是如何工作的,就像标题中所说的:我也不知道如何从DH类获取密钥,并在AES类中声明这是它必须用来加密的密钥
欢迎提供关于代码优化、更好实践和一般提示的建议。 谢谢你抽出时间
公共类DH扩展线程{
int bitLength=512;
int certainty=20;//
private static final SecureRandom rnd = new SecureRandom();
public DH() throws Exception{
Random randomGenerator = new Random();
BigInteger generatorValue,primeValue,publicA,publicB,secretA,secretB,sharedKeyA,sharedKeyB;
primeValue = findPrime();// BigInteger.valueOf((long)g);
System.out.println("the prime is "+primeValue);
generatorValue = findPrimeRoot(primeValue);//BigInteger.valueOf((long)p);
System.out.println("the generator of the prime is "+generatorValue);
// on machine 1
secretA = new BigInteger(bitLength-2,randomGenerator);
// on machine 2
secretB = new BigInteger(bitLength-2,randomGenerator);
// to be published:
publicA=generatorValue.modPow(secretA, primeValue);
publicB=generatorValue.modPow(secretB, primeValue);
sharedKeyA = publicB.modPow(secretA,primeValue);// should always be same as:
sharedKeyB = publicA.modPow(secretB,primeValue);
String getAValue=sharedKeyA.toString();
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(getAValue.getBytes());
byte byteData[] = md.digest();
StringBuffer sb = new StringBuffer();
for(int i=0;i<byteData.length;i++)
{
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));// ??
}
String getHexValue = sb.toString();
System.out.println("hex format in SHA-256 is "+getHexValue);
byte [] initkey = getAValue.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-256");
initkey = sha.digest(initkey);
initkey = Arrays.copyOf(initkey, 16);
SecretKeySpec secretKeySpec = new SecretKeySpec(initkey,"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
}
正如您所看到的,我已经静态地编码了AES密钥和IV,但是希望在DH中生成的AES密钥被分配到这个类中
公共类AES{
static String IV = "AAAAAAAAAAAAAAAA";
static String initkey = "13B_0(wcXNGkHAR[";
public static byte[] encrypt(byte[] plainData, int offset, int length) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//CBC
SecretKeySpec key = new SecretKeySpec(initkey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(plainData, offset, length);
}
public static byte[] decrypt(byte[] cipherSound, int offset, int length) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//CBC
SecretKeySpec key = new SecretKeySpec(initkey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(cipherSound, offset, length);
}
}
# 1 楼答案
请检查这个tutorial
然后你可以使用返回的秘密:
但是,如果您有双向通信,则每个方向都需要随机IV键或不同的键(源于主控键)
其他提示:
也许你的设备足够强大,可以建立适当的TLS,什么能为你解决很多问题