安全でないチャネルを介して機密データを送信することを含むJavaの個人プロジェクトに取り組んでいます。ライブラリを使用して、Diffie Hellman Key Exchange(DHKE)をJavaに実装する方法を知る必要があります。私はそれに関するすべての暗号理論を知っているので、詳細に進む必要はありません。非常に基本的な実装が必要なので、2つのプログラムで秘密鍵を共有できます。 Java2s.comから例を入手しましたが、完全ではありません。
import Java.math.BigInteger;
import Java.security.KeyFactory;
import Java.security.KeyPair;
import Java.security.KeyPairGenerator;
import Java.security.SecureRandom;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPublicKeySpec;
public class Main {
public final static int pValue = 47;
public final static int gValue = 71;
public final static int XaValue = 9;
public final static int XbValue = 14;
public static void main(String[] args) throws Exception {
BigInteger p = new BigInteger(Integer.toString(pValue));
BigInteger g = new BigInteger(Integer.toString(gValue));
BigInteger Xa = new BigInteger(Integer.toString(XaValue));
BigInteger Xb = new BigInteger(Integer.toString(XbValue));
int bitLength = 512; // 512 bits
SecureRandom rnd = new SecureRandom();
p = BigInteger.probablePrime(bitLength, rnd);
g = BigInteger.probablePrime(bitLength, rnd);
createSpecificKey(p, g);
}
public static void createSpecificKey(BigInteger p, BigInteger g) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DiffieHellman");
DHParameterSpec param = new DHParameterSpec(p, g);
kpg.initialize(param);
KeyPair kp = kpg.generateKeyPair();
KeyFactory kfactory = KeyFactory.getInstance("DiffieHellman");
DHPublicKeySpec kspec = (DHPublicKeySpec) kfactory.getKeySpec(kp.getPublic(),
DHPublicKeySpec.class);
}
}
これからどうすればいいですか?残りのコードを完了するのを手伝ってくれる人はいますか?
公式のOracle Docs はどうですか?そこでは、DHキー交換がコードで示されています。
次のコードは、Elliptic Curve Diffie-Hellmanを使用して、暗号化用の128ビットキーとAESを生成および共有します。
import Sun.misc.BASE64Decoder;
import Sun.misc.BASE64Encoder;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import Java.io.IOException;
import Java.security.*;
public class AESSecurityCap {
private PublicKey publickey;
KeyAgreement keyAgreement;
byte[] sharedsecret;
String ALGO = "AES";
AESSecurityCap() {
makeKeyExchangeParams();
}
private void makeKeyExchangeParams() {
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(128);
KeyPair kp = kpg.generateKeyPair();
publickey = kp.getPublic();
keyAgreement = KeyAgreement.getInstance("ECDH");
keyAgreement.init(kp.getPrivate());
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}
public void setReceiverPublicKey(PublicKey publickey) {
try {
keyAgreement.doPhase(publickey, true);
sharedsecret = keyAgreement.generateSecret();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
public String encrypt(String msg) {
try {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(msg.getBytes());
return new BASE64Encoder().encode(encVal);
} catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return msg;
}
public String decrypt(String encryptedData) {
try {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
return new String(decValue);
} catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
return encryptedData;
}
public PublicKey getPublickey() {
return publickey;
}
protected Key generateKey() {
return new SecretKeySpec(sharedsecret, ALGO);
}
}
独自のクラスを拡張してAES暗号化機能を追加する
public class Node extends AESSecurityCap {
//your class
}
最後に、暗号化を使用する方法
public class Main {
public static void main(String[] args) throws IOException {
Node server = new Node();
Node client = new Node();
server.setReceiverPublicKey(client.getPublickey());
client.setReceiverPublicKey(server.getPublickey());
String data = "hello";
String enc = server.encrypt(data);
System.out.println("hello is coverted to "+enc);
System.out.println(enc+" is converted to "+client.decrypt(enc));
}
}
出力:
hello is coverted to OugbNvUuylvAr9mKv//nLA==
OugbNvUuylvAr9mKv//nLA== is converted to hello
Process finished with exit code 0
これが作業例です:
static void main() {
DH dh = new DH();
byte[] myPublicKey = dh.generatePublicKey();
/* Send myPublicKey to other party, and get hisPublicKey in return */
byte[] sharedKey = dh.computeSharedKey(hisPublicKey)
/* sharedKey is now 'shared' between both parties */
}
public class DH {
private static final String TAG = "DH";
private KeyPair keyPair;
private KeyAgreement keyAgree;
public byte[] generatePublicKey() {
DHParameterSpec dhParamSpec;
try {
dhParamSpec = new DHParameterSpec(P, G);
Log.i(TAG, "P = " + P.toString(16));
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DiffieHellman");
keyPairGen.initialize(dhParamSpec);
keyPair = keyPairGen.generateKeyPair();
Log.i(TAG, "Y = " + ((DHPublicKey) keyPair.getPublic()).getY().toString(16));
keyAgree = KeyAgreement.getInstance("DiffieHellman");
keyAgree.init(keyPair.getPrivate());
BigInteger pubKeyBI = ((DHPublicKey) keyPair.getPublic()).getY();
byte[] pubKeyBytes = pubKeyBI.toByteArray();
Log.i(TAG, String.format(TAG, "Y [%d] = %s", pubKeyBytes.length, Utils.toHexString(pubKeyBytes)));
return pubKeyBytes;
} catch (Exception e) {
Log.e(TAG, "generatePubKey(): " + e.getMessage());
return null;
}
}
public byte[] computeSharedKey(byte[] pubKeyBytes) {
if (keyAgree == null) {
Log.e(TAG, "computeSharedKey(): keyAgree IS NULL!!");
return null;
}
try {
KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
BigInteger pubKeyBI = new BigInteger(1, pubKeyBytes);
Log.i(TAG, "Y = " + pubKeyBI.toString(16));
PublicKey pubKey = keyFactory.generatePublic(new DHPublicKeySpec(pubKeyBI, P, G));
keyAgree.doPhase(pubKey, true);
byte[] sharedKeyBytes = keyAgree.generateSecret();
Log.i(TAG, String.format("SHARED KEY[%d] = %s", sharedKeyBytes.length, Utils.toHexString(sharedKeyBytes)));
return sharedKeyBytes;
} catch (Exception e) {
Log.e(TAG, "computeSharedKey(): " + e.getMessage());
return null;
}
}
private static final byte P_BYTES[] = {
(byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58,
...
(byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7
};
private static final BigInteger P = new BigInteger(1, P_BYTES);
private static final BigInteger G = BigInteger.valueOf(2);
}