In: Computer Science
how to write program in java for encrypt and decrypt input text using DH algorithm
import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; |
||||
import java.security.InvalidKeyException; |
||||
import java.security.Key; |
||||
import java.security.KeyPair; |
||||
import java.security.KeyPairGenerator; |
||||
import java.security.NoSuchAlgorithmException; |
||||
import java.security.NoSuchProviderException; |
||||
import java.security.PrivateKey; |
||||
import java.security.PublicKey; |
||||
import java.security.SecureRandom; |
||||
import java.util.Enumeration; |
||||
import javax.crypto.BadPaddingException; |
||||
import javax.crypto.Cipher; |
||||
import javax.crypto.IllegalBlockSizeException; |
||||
import javax.crypto.KeyAgreement; |
||||
import javax.crypto.NoSuchPaddingException; |
||||
import javax.crypto.SecretKey; |
||||
import javax.crypto.ShortBufferException; |
||||
import javax.crypto.spec.IvParameterSpec; |
||||
import javax.crypto.spec.SecretKeySpec; |
||||
import org.bouncycastle.jce.ECNamedCurveTable; |
||||
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; |
||||
public class Test { |
||||
public static byte[] iv = new SecureRandom().generateSeed(16); |
||||
public static void main(String[] args) { |
||||
String plainText = "Look mah, I'm a message!"; |
||||
System.out.println("Original plaintext message: " + plainText); |
||||
// Initialize two key pairs |
||||
KeyPair keyPairA = generateECKeys(); |
||||
KeyPair keyPairB = generateECKeys(); |
||||
// Create two AES secret keys to encrypt/decrypt the message |
||||
SecretKey secretKeyA = generateSharedSecret(keyPairA.getPrivate(), |
||||
keyPairB.getPublic()); |
||||
SecretKey secretKeyB = generateSharedSecret(keyPairB.getPrivate(), |
||||
keyPairA.getPublic()); |
||||
// Encrypt the message using 'secretKeyA' |
||||
String cipherText = encryptString(secretKeyA, plainText); |
||||
System.out.println("Encrypted cipher text: " + cipherText); |
||||
// Decrypt the message using 'secretKeyB' |
||||
String decryptedPlainText = decryptString(secretKeyB, cipherText); |
||||
System.out.println("Decrypted cipher text: " + decryptedPlainText); |
||||
} |
||||
public static KeyPair generateECKeys() { |
||||
try { |
||||
ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec("brainpoolp256r1"); |
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( |
||||
"ECDH", "BC"); |
||||
keyPairGenerator.initialize(parameterSpec); |
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair(); |
||||
|
||||
return keyPair; |
||||
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException |
||||
| NoSuchProviderException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
public static SecretKey generateSharedSecret(PrivateKey privateKey, |
||||
PublicKey publicKey) { |
||||
try { |
||||
KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH", "BC"); |
||||
keyAgreement.init(privateKey); |
||||
keyAgreement.doPhase(publicKey, true); |
||||
SecretKey key = keyAgreement.generateSecret("AES"); |
||||
return key; |
||||
} catch (InvalidKeyException | NoSuchAlgorithmException |
||||
| NoSuchProviderException e) { |
||||
// TODO Auto-generated catch block |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
public static String encryptString(SecretKey key, String plainText) { |
||||
try { |
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv); |
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); |
||||
byte[] plainTextBytes = plainText.getBytes("UTF-8"); |
||||
byte[] cipherText; |
||||
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); |
||||
cipherText = new byte[cipher.getOutputSize(plainTextBytes.length)]; |
||||
int encryptLength = cipher.update(plainTextBytes, 0, |
||||
plainTextBytes.length, cipherText, 0); |
||||
encryptLength += cipher.doFinal(cipherText, encryptLength); |
||||
return bytesToHex(cipherText); |
||||
} catch (NoSuchAlgorithmException | NoSuchProviderException |
||||
| NoSuchPaddingException | InvalidKeyException |
||||
| InvalidAlgorithmParameterException |
||||
| UnsupportedEncodingException | ShortBufferException |
||||
| IllegalBlockSizeException | BadPaddingException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
public static String decryptString(SecretKey key, String cipherText) { |
||||
try { |
||||
Key decryptionKey = new SecretKeySpec(key.getEncoded(), |
||||
key.getAlgorithm()); |
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv); |
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); |
||||
byte[] cipherTextBytes = hexToBytes(cipherText); |
||||
byte[] plainText; |
||||
cipher.init(Cipher.DECRYPT_MODE, decryptionKey, ivSpec); |
||||
plainText = new byte[cipher.getOutputSize(cipherTextBytes.length)]; |
||||
int decryptLength = cipher.update(cipherTextBytes, 0, |
||||
cipherTextBytes.length, plainText, 0); |
||||
decryptLength += cipher.doFinal(plainText, decryptLength); |
||||
return new String(plainText, "UTF-8"); |
||||
} catch (NoSuchAlgorithmException | NoSuchProviderException |
||||
| NoSuchPaddingException | InvalidKeyException |
||||
| InvalidAlgorithmParameterException |
||||
| IllegalBlockSizeException | BadPaddingException |
||||
| ShortBufferException | UnsupportedEncodingException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
public static String bytesToHex(byte[] data, int length) { |
||||
String digits = "0123456789ABCDEF"; |
||||
StringBuffer buffer = new StringBuffer(); |
||||
for (int i = 0; i != length; i++) { |
||||
int v = data[i] & 0xff; |
||||
buffer.append(digits.charAt(v >> 4)); |
||||
buffer.append(digits.charAt(v & 0xf)); |
||||
} |
||||
return buffer.toString(); |
||||
} |
||||
public static String bytesToHex(byte[] data) { |
||||
return bytesToHex(data, data.length); |
||||
} |
||||
public static byte[] hexToBytes(String string) { |
||||
int length = string.length(); |
||||
byte[] data = new byte[length / 2]; |
||||
for (int i = 0; i < length; i += 2) { |
||||
data[i / 2] = (byte) ((Character.digit(string.charAt(i), 16) << 4) + Character |
||||
.digit(string.charAt(i + 1), 16)); |
||||
} |
||||
return data; |
||||
} |
||||
} Output: Original plaintext message : Look mah, I'm a message!
Decrypted cipher text: Look mah, I'm a message!
|