Last active
September 15, 2020 07:27
-
-
Save debuggor/1432c4125adba9843efff05ed8fbff07 to your computer and use it in GitHub Desktop.
ecdh key exchange ; aes-256-gcm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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