Java 11 – ChaCha20-Poly1305加密示例
本文向您展示如何使用RFC 7539中定義的ChaCha20-Poly1305算法對消息進行加密和解密。
PS ChaCha20-Poly1305加密算法可從Java 11獲得。
1.常見問題
一些常見問題:
1.1什么是ChaCha20-Poly1305 ?
ChaCha20-Poly1305表示使用Poly1305身份驗證器以AEAD模式運行的ChaCha20 (加密和解密算法)。
1.2什么是AE或AEAD?
認證加密(AE)和帶有關聯數據的認證加密(AEAD)是一種加密消息并一起認證加密的形式。
1.3認證加密意味著什么?
確保沒有人修改密文(加密的消息),它的工作方式類似于驗證文件的SHA或MD5哈希。 Poly1305生成一個MAC (消息驗證碼)(128位,16字節),并將其附加到ChaCha20密文(加密的文本)中。 在解密過程中,該算法檢查MAC以確保沒有人修改密文。
1.4 ChaCha20-Poly1305如何工作?
ChaCha20加密使用密鑰和IV(初始化值,nonce)將明文加密為等長的密文。 Poly1305生成一個MAC(消息認證碼)并將其附加到密文中。 最后,密文和明文的長度不同。
1.5我可以將同一隨機數重用于不同的密鑰嗎?
不可以,每個加密的隨機數和密鑰都必??須是唯一的,否則密文會妥協!
注意
如果我們不需要額外的身份驗證(poly1305)功能,請考慮僅使用ChaCha20加密消息,請參閱此Java 11 – ChaCha20流密碼示例
1. ChaCha20-Poly1305
本示例使用ChaCha20-Poly1305加密和解密消息。 此外,我們手動將隨機數附加到最終的加密文本上,以便在解密期間無需提供隨機數。 隨機數可以公開,但密鑰必須是私有的。
ChaCha20-Poly1305的輸入為:
- 256位密鑰(32字節)
- 96位隨機數(12個字節)
PS對于ChaCha20-Poly1305 ,我們不需要定義初始計數器值。 它從1開始。
ChaCha20Poly1305.java package com.mkyong.java11.jep329.poly1305;import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import java.nio.ByteBuffer; import java.security.SecureRandom;public class ChaCha20Poly1305 {private static final String ENCRYPT_ALGO = "ChaCha20-Poly1305";private static final int NONCE_LEN = 12; // 96 bits, 12 bytes// if no nonce, generate a random 12 bytes noncepublic byte[] encrypt(byte[] pText, SecretKey key) throws Exception {return encrypt(pText, key, getNonce());}public byte[] encrypt(byte[] pText, SecretKey key, byte[] nonce) throws Exception {Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);// IV, initialization value with nonceIvParameterSpec iv = new IvParameterSpec(nonce);cipher.init(Cipher.ENCRYPT_MODE, key, iv);byte[] encryptedText = cipher.doFinal(pText);// append nonce to the encrypted textbyte[] output = ByteBuffer.allocate(encryptedText.length + NONCE_LEN).put(encryptedText).put(nonce).array();return output;}public byte[] decrypt(byte[] cText, SecretKey key) throws Exception {ByteBuffer bb = ByteBuffer.wrap(cText);// split cText to get the appended noncebyte[] encryptedText = new byte[cText.length - NONCE_LEN];byte[] nonce = new byte[NONCE_LEN];bb.get(encryptedText);bb.get(nonce);Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);IvParameterSpec iv = new IvParameterSpec(nonce);cipher.init(Cipher.DECRYPT_MODE, key, iv);// decrypted textbyte[] output = cipher.doFinal(encryptedText);return output;}// 96-bit nonce (12 bytes)private static byte[] getNonce() {byte[] newNonce = new byte[12];new SecureRandom().nextBytes(newNonce);return newNonce;}}2.測試一下。
使用ChaCha20-Poly1305算法對消息進行加密和解密。
TestChaCha20Poly1305.java package com.mkyong.java11.jep329.poly1305;import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom;public class TestChaCha20Poly1305 {private static final int NONCE_LEN = 12; // 96 bits, 12 bytesprivate static final int MAC_LEN = 16; // 128 bits, 16 bytespublic static void main(String[] args) throws Exception {String input = "Java & ChaCha20-Poly1305.";ChaCha20Poly1305 cipher = new ChaCha20Poly1305();SecretKey key = getKey(); // 256-bit secret key (32 bytes)System.out.println("Input : " + input);System.out.println("Input (hex): " + convertBytesToHex(input.getBytes()));System.out.println("\n---Encryption---");byte[] cText = cipher.encrypt(input.getBytes(), key); // encryptSystem.out.println("Key (hex): " + convertBytesToHex(key.getEncoded()));System.out.println("Encrypted (hex): " + convertBytesToHex(cText));System.out.println("\n---Print Mac and Nonce---");ByteBuffer bb = ByteBuffer.wrap(cText);// This cText contains chacha20 ciphertext + poly1305 MAC + nonce// ChaCha20 encrypted the plaintext into a ciphertext of equal length.byte[] originalCText = new byte[input.getBytes().length];byte[] nonce = new byte[NONCE_LEN]; // 16 bytes , 128 bitsbyte[] mac = new byte[MAC_LEN]; // 12 bytes , 96 bitsbb.get(originalCText);bb.get(mac);bb.get(nonce);System.out.println("Cipher (original) (hex): " + convertBytesToHex(originalCText));System.out.println("MAC (hex): " + convertBytesToHex(mac));System.out.println("Nonce (hex): " + convertBytesToHex(nonce));System.out.println("\n---Decryption---");System.out.println("Input (hex): " + convertBytesToHex(cText));byte[] pText = cipher.decrypt(cText, key); // decryptSystem.out.println("Key (hex): " + convertBytesToHex(key.getEncoded()));System.out.println("Decrypted (hex): " + convertBytesToHex(pText));System.out.println("Decrypted : " + new String(pText));}// https://mkyong.com/java/java-how-to-convert-bytes-to-hex/private static String convertBytesToHex(byte[] bytes) {StringBuilder result = new StringBuilder();for (byte temp : bytes) {result.append(String.format("%02x", temp));}return result.toString();}// A 256-bit secret key (32 bytes)private static SecretKey getKey() throws NoSuchAlgorithmException {KeyGenerator keyGen = KeyGenerator.getInstance("ChaCha20");keyGen.init(256, SecureRandom.getInstanceStrong());return keyGen.generateKey();}}輸出量
Terminal Input : Java & ChaCha20-Poly1305. Input (hex): 4a61766120262043686143686132302d506f6c79313330352e---Encryption--- Key (hex): 7b47d646547928f2ac962562d613bdac7db351893224c6c1b03adeb859da8251 Encrypted (hex): c04a463086c545d0053f8a279d50815aa9cb5db04da5ba0c4dc57e225f46074af793ccb81a15908a8fd15561deb55f01ef0d93932a---Print Mac and Nonce--- Cipher (original) (hex): c04a463086c545d0053f8a279d50815aa9cb5db04da5ba0c4d MAC (hex): c57e225f46074af793ccb81a15908a8f Nonce (hex): d15561deb55f01ef0d93932a---Decryption--- Input (hex): c04a463086c545d0053f8a279d50815aa9cb5db04da5ba0c4dc57e225f46074af793ccb81a15908a8fd15561deb55f01ef0d93932a Key (hex): 7b47d646547928f2ac962562d613bdac7db351893224c6c1b03adeb859da8251 Decrypted (hex): 4a61766120262043686143686132302d506f6c79313330352e Decrypted : Java & ChaCha20-Poly1305.下載源代碼
$ git clone https://github.com/mkyong/core-java.git
$ cd java-11
$ cd / src / main / java / com / mkyong / java11 / jep329
注意
如果發現任何錯誤,請在下面發表評論,謝謝。
參考文獻
- ChaCha20
- RFC 7539
- 維基百科– Authenticated_encryption
- Java 11 – ChaCha20流密碼示例
翻譯自: https://mkyong.com/java/java-11-chacha20-poly1305-encryption-examples/
總結
以上是生活随笔為你收集整理的Java 11 – ChaCha20-Poly1305加密示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bat 打开 任务管理器
- 下一篇: java pippo_【Java资源大全