将PHP Rijndael算法重写为Java(Android)
我需要在
Java和php中编码一个字符串,其结果必须相同.
给出以下条件: >算法:RIJNDAEL-128 要编码的字符串:201412181656005P443m2Q1R9A7f5r3e1z08642 PHP <?php class Cipher { private $securekey,$iv; function __construct($textkey) { $this->securekey = $textkey; $this->iv = mcrypt_create_iv(32); } function encryptR($input) { $enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$this->securekey,$input,MCRYPT_MODE_ECB,$this->iv); return base64_encode($enc); } function decryptR($input) { return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128,base64_decode($input),$this->iv)); } } $raw_text = '201412181656005P443m2Q1R9A7f5r3e1z08642'; $secretKey = '5P443m2Q1R9A7f5r3e1z08642'; $cipher = new Cipher($secretKey); $encrypted = $cipher->encryptR($raw_text); ?> 输出:MbDHhIanWgySlMTOX ItgVKudVLXbtj7ig2GMQacVM9JhyAPvVQxLJnHpEj / vhqW JAVA encrypted = encrypt("201412181656005P443m2Q1R9A7f5r3e1z08642","5P443m2Q1R9A7f5r3e1z08642"); public class Crypt { private final String characterEncoding = "UTF-8"; private final String cipherTransformation = "AES/ECB/PKCS5Padding"; private final String aesEncryptionAlgorithm = "AES"; public byte[] decrypt(byte[] cipherText,byte[] key) throws Exception { Cipher cipher = Cipher.getInstance(cipherTransformation); SecretKeySpec secretKeySpecy = new SecretKeySpec(key,aesEncryptionAlgorithm); cipher.init(Cipher.DECRYPT_MODE,secretKeySpecy); cipherText = cipher.doFinal(cipherText); return cipherText; } public byte[] encrypt(byte[] plainText,byte[] key) throws Exception { Cipher cipher = Cipher.getInstance(cipherTransformation); SecretKeySpec secretKeySpec = new SecretKeySpec(key,aesEncryptionAlgorithm); cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec); plainText = cipher.doFinal(plainText); return plainText; } private byte[] getKeyBytes(String key) throws UnsupportedEncodingException{ byte[] keyBytes= new byte[16]; byte[] parameterKeyBytes= key.getBytes(characterEncoding); System.arraycopy(parameterKeyBytes,keyBytes,Math.min(parameterKeyBytes.length,keyBytes.length)); return keyBytes; } @SuppressLint("NewApi") public String encrypt(String plainText,String key) throws Exception { byte[] plainTextbytes = plainText.getBytes(characterEncoding); byte[] keyBytes = getKeyBytes(key); // Log.i("iv",""+keyBytesIV); return Base64.encodeToString(encrypt(plainTextbytes,keyBytes),Base64.DEFAULT); } @SuppressLint("NewApi") public String decrypt(String encryptedText,String key) throws Exception { byte[] cipheredBytes = Base64.decode(encryptedText,Base64.DEFAULT); byte[] keyBytes = getKeyBytes(key); return new String(decrypt(cipheredBytes,characterEncoding); } } 输出:wd0FHYpLbgdpHhcSql7VVCiKWJWN5hvP0W9F4sgKWAWeDcSjvfKWTM5LHBCZJSRw 更新: 我将填充从NoPadding更改为PKCS5Padding 它是否正确?我不确定,因为你看看PHP代码.没有指定任何填充(我自己基于语法的假设). Info on Mcrypt 额外洞察力: 阅读此document关于填充(无填充).一定是和这个问题有关.
看起来您的PHP版本使用AES-128,根据定义,它使用128位(16字节)密钥.然而,看起来你传入了一个25字节的密钥(5P443m2Q1R9A7f5r3e1z08642),我不确定当发生这种情况时PHP会做什么.
您的Java版本的getKeyBytes()方法仅返回提供的密钥的前16个字节,因此仅使用它加密. 尝试将PHP版本中的密钥截断为5P443m2Q1R9A7f5r,您将得到相同的结果.除了可能不同的末端部分.那时,问题就是填充.您可以在明文上应用pkcs5_pad PHP函数,使其与您的Java版本匹配. 所有这一切,如果这只是为了学习目的,那没关系.否则,对于实际使用,重要的是你do not use ECB cipher mode. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |