Java和rust的AES加解密算法互相转化,秘钥key格式不一致带来的问题
rust程序秘钥
[186, 203, 37, 76, 34, 98, 59, 142, 141, 247, 60, 104, 212, 189, 2, 64]
rust矢量向量
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 9]
问题点:
在 Rust 中,[u8; 16] 表示一个固定长度为 16 的无符号字节数组,是加密、网络传输等场景中非常常见的数据类型(例如 AES-128 密钥、16 字节初始向量 IV 等)。
而Java中的秘钥是byte[]类型的,而byte是有符号的,无法表示大于127的数字
解决办法:Java将无符号的字节数组转换为无符号的
byte[] keyBytes = {(byte)186,(byte)203,(byte)37,(byte)76,(byte)34,(byte)98,(byte)59,(byte)142,(byte)141,(byte)247,(byte)60,(byte)104,(byte)212,(byte)189,(byte)2,(byte)64};
完整的代码如下:
Java AES加解密算法
public class AESExample {public static void main(String[] args) throws Exception {//密钥byte[] keyBytes = {(byte)186,(byte)203,(byte)37,(byte)76,(byte)34,(byte)98,(byte)59,(byte)142,(byte)141,(byte)247,(byte)60,(byte)104,(byte)212,(byte)189,(byte)2,(byte)64};SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");// 生成IV(对于CTR模式,IV很重要,因为它用作计数器的初始值)byte[] iv = new byte[16]; // AES-128使用128位IV,但CTR通常使用固定长度的计数器,例如16字节iv[15] = 9;Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); // 注意:CTR通常不需要填充模式cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));byte[] input = "%22Hello%20World!%22".getBytes(); // 明文数据byte[] encrypted = cipher.doFinal(input); // 加密数据System.out.println("Encrypted: " + bytesToHex(encrypted)); // 打印加密后的数据,用于显示或存储cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv)); // 重用相同的IV和密钥进行解密byte[] decrypted = cipher.doFinal(hexToBytes("cba80e1110facd2678b8880bc60295bbd7d53631")); // 解密数据System.out.println("Decrypted: " + new String(decrypted)); // 打印解密后的数据System.out.println("end: " );}public static String bytesToHex(byte[] bytes) {StringBuilder sb = new StringBuilder();for (byte b : bytes) {sb.append(String.format("%02x", b));}return sb.toString();}public static byte[] hexToBytes(String hexString) {// 检查字符串长度是否为偶数if (hexString == null || hexString.length() % 2 != 0) {throw new IllegalArgumentException("无效的16进制字符串");}int length = hexString.length();byte[] result = new byte[length / 2];for (int i = 0; i < length; i += 2) {// 每两个字符转换为一个字节(16进制转10进制)int high = Character.digit(hexString.charAt(i), 16); // 高位int low = Character.digit(hexString.charAt(i + 1), 16); // 低位result[i / 2] = (byte) ((high << 4) + low); // 组合为一个字节}return result;}
rust版AES加密算法:
use aes::Aes128;
use ctr::Ctr128;
use crypto_common::{KeyInit, iv::Iv};
use std::fmt::Write;// 定义AES-CTR加密器类型
type AesCtr = Ctr128<Aes128>;fn main() -> Result<(), Box<dyn std::error::Error>> {// 待加密的字符串let plaintext = "Hello World!";println!("原始字符串: {}", plaintext);// 16字节密钥let key = [186, 203, 37, 76, 34, 98, 59, 142, 141, 247, 60, 104, 212, 189, 2, 64];// 16字节初始向量(IV)let iv = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9];// 执行加密let ciphertext = encrypt(plaintext.as_bytes(), &key, &iv)?;// 以十六进制格式输出加密结果let mut hex_result = String::new();for byte in &ciphertext {write!(hex_result, "{:02x}", byte)?;}println!("加密结果(十六进制): {}", hex_result);// 以Base64格式输出加密结果let base64_result = base64::encode(&ciphertext);println!("加密结果(Base64): {}", base64_result);Ok(())
}/// 使用AES-128-CTR模式加密数据
fn encrypt(data: &[u8], key: &[u8; 16], iv: &[u8; 16]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {// 创建AES加密器实例let cipher = Aes128::new_from_slice(key)?;// 初始化CTR模式加密器let mut ctr = AesCtr::new(&cipher, Iv::from_slice(iv));// 加密数据(CTR模式中加密和解密使用相同的操作)let mut buffer = data.to_vec();ctr.apply_keystream(&mut buffer);Ok(buffer)
}