Skip to content

Instantly share code, notes, and snippets.

@debuggor
Last active September 15, 2020 07:27
Show Gist options
  • Save debuggor/1432c4125adba9843efff05ed8fbff07 to your computer and use it in GitHub Desktop.
Save debuggor/1432c4125adba9843efff05ed8fbff07 to your computer and use it in GitHub Desktop.
ecdh key exchange ; aes-256-gcm
import org.bitcoinj.core.Utils;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
/**
* @Author:yong.huang
* @Date:2020-07-16 18:13
*/
public class Aes256Gcm {
public static final int GCM_IV_LENGTH = 12;
public static final int GCM_TAG_LENGTH = 16;
public static byte[] encryptAES256GCM(byte[] plaintext, byte[] secret, byte[] nonce) throws Exception {
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(secret, "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
// Initialize Cipher for ENCRYPT_MODE
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Encryption
return cipher.doFinal(plaintext);
}
public static String decryptAES256GCM(byte[] cipherText, byte[] secret, byte[] nonce) throws Exception {
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(secret, "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Decryption
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText);
}
public static void main(String[] args) throws Exception {
byte[] secret = Utils.HEX.decode("88daf6993cd89eb2f95da19c961962ed1ed017edb44816e778497538e06e86fb");
int GCM_IV_LENGTH = 12;
byte[] nonce = new byte[GCM_IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(nonce);
String plainText = "{\"jsonrpc\":\"2.0\",\"method\":\"open_wallet\",\"id\":1,\"params\":{\"name\":null,\"password\":\"\"}}";
System.out.println("Original Text : " + plainText);
byte[] cipherText = Aes256Gcm.encryptAES256GCM(plainText.getBytes(), secret, nonce);
System.out.println("Encrypted Text : " + Base64.getEncoder().encodeToString(cipherText));
String decryptedText = Aes256Gcm.decryptAES256GCM(cipherText, secret, nonce);
System.out.println("Decrypted Text : " + decryptedText);
}
}
import org.apache.commons.codec.binary.Hex;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Utils;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import javax.crypto.KeyAgreement;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
/**
* @Author:yong.huang
* @Date:2020-07-16 18:12
*/
public class EcdhKeyExchange {
public static byte[] computeSecret(byte[] priv, byte[] otherPub) throws Exception {
KeyAgreement ka = KeyAgreement.getInstance("ECDH", "BC");
PrivateKey privateKey = loadPrivateKey(priv);
PublicKey publicKey = loadPublicKey(otherPub);
ka.init(privateKey);
ka.doPhase(publicKey, true);
byte[] secret = ka.generateSecret();
return secret;
}
private static PrivateKey loadPrivateKey(byte[] priv) throws Exception {
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
ECPrivateKeySpec keySpec = new ECPrivateKeySpec(new BigInteger(priv), params);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
return kf.generatePrivate(keySpec);
}
private static PublicKey loadPublicKey(byte[] pub) throws Exception {
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
ECPublicKeySpec pubKey = new ECPublicKeySpec(params.getCurve().decodePoint(pub), params);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
return kf.generatePublic(pubKey);
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
String priv = "465568154bbf7448f2678cd4ef08fa0ae8e57a6a978e032386860f34e86f9507";
ECKey ecKey = ECKey.fromPrivate(new BigInteger(priv, 16));
byte[] privKeyBytes = ecKey.getPrivKeyBytes();
String otherPub = "03a9120b42a6d8d4051af874c230841e5794367bb8792c55bcb1ce2e379cc9a826";
byte[] secret = EcdhKeyExchange.computeSecret(privKeyBytes, Utils.HEX.decode(otherPub));
System.out.println("secret:" + Hex.encodeHexString(secret));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment