背景:我有两个设备通过IP /端口连接进行通信,这要归功于Diffie-Hellman密钥交换,并通过AES算法对实时语音加密通信进行加密。现在,已编写了一些代码,而有些仅用作原型实现的示例。
问题:现在,即使理解我的类的工作方式就像标题所述:我不知道如何从DH类中获取密钥并在AES类中声明这是加密所必须使用的密钥。
P.s。欢迎提供有关代码优化,更好的做法和一般提示的建议。谢谢您的时间。
公共类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);
}
}
弄清楚如何从DH类中获取密钥并在AES类中声明这是必须用于加密的密钥
请检查此tutorial
然后您可以使用返回的机密:
byte[] masterKey = aKeyAgree.generateSecret();
// maybe hash the master key too
SecretKeySpec key = new SecretKeySpec(masterKey, 0, 16, "AES");
但是,如果您使用双向通信,则每个方向都需要随机IV或不同的键(从主机获取)
附加提示:
我有两个通过IP /端口连接进行通信以建立实时语音加密通信的设备
也许您的设备足够强大,可以建立适当的TLS,这将为您解决很多问题