Rijndael 256 encryption with Java & Bouncy Castle
我正在开发一个使用纯PHP构建的项目,正在对登录进行重做,但是数据库中的用户使用Rijndael-256加密,我尝试了很多事情,但似乎没有任何效果,并且 我觉得我与这段代码非常接近,但是它不起作用,我真的迷路了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | private final String key ="..."; public String decrypt(String password, String cypherKey) { try { password = password.substring(0, password.lenght() - 1); // 1 byte[] passwordBytes = password.getBytes("UTF-8"); byte[] key = cypherKey.getBytes("UTF-8"); RijndaelEngine rijndaelEngine = new RijndaelEngine(256); KeyParameter keyParam = new KeyParameter(key); rijndaelEngine.init(false, keyParam); // 2 PaddedBufferedBlockCipher bufferedBlock = new PaddedBufferedBlockCipher(rijndaelEngine, new ZeroBytePadding()); byte[] decryptedBytes = new byte[bufferedBlock.getOutputSize(passwordBytes.length)]; int processed = bufferedBlock.processBytes(passwordBytes, 0, passwordBytes.length, decryptedBytes, 0); return String.valueOf(bufferedBlock.doFinal(decryptedBytes, processed)); } catch (Exeption e) { e.printStackTrace(); } return""; // I know this is awful but i was trying something and left this like that } |
* 1)我不知道这是否正确,但是所有加密的密码都以等号结尾,并且我使用加密工具进行了测试,我认为这不是必需的
2)False是解密模式
堆栈跟踪:org.bouncycastle.crypto.DataLengthException:解密中的最后一个块不完整
我现在正在进行这种解密两个星期,我真的很拼命:(
PHP代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | function fnEncrypt($sValue) { include("constants.php"); return trim( base64_encode( mcrypt_encrypt( MCRYPT_RIJNDAEL_256, $SecretKey, $sValue, MCRYPT_MODE_ECB, mcrypt_create_iv( mcrypt_get_iv_size( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB ), MCRYPT_RAND) ) ) ); } function fnDecrypt($sValue) { include("constants.php"); return trim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sValue), MCRYPT_MODE_ECB, mcrypt_create_iv( mcrypt_get_iv_size( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB ), MCRYPT_RAND ) ) ); } |
在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //password = password.substring(0, password.lenght() - 1); // 1 // Remove //byte[] passwordBytes = password.getBytes("UTF-8"); // Remove byte[] passwordBytes = Base64.getDecoder().decode(password); // Base64-decode the ciphertext (1) byte[] key = cypherKey.getBytes("UTF-8"); RijndaelEngine rijndaelEngine = new RijndaelEngine(256); KeyParameter keyParam = new KeyParameter(key); rijndaelEngine.init(false, keyParam); // 2 PaddedBufferedBlockCipher bufferedBlock = new PaddedBufferedBlockCipher(rijndaelEngine, new ZeroBytePadding()); byte[] decryptedBytes = new byte[bufferedBlock.getOutputSize(passwordBytes.length)]; int processed = bufferedBlock.processBytes(passwordBytes, 0, passwordBytes.length, decryptedBytes, 0); processed += bufferedBlock.doFinal(decryptedBytes, processed); // Refresh the parameter containing the length of the decrypted data (2a) decryptedBytes = Arrays.copyOfRange(decryptedBytes, 0, processed); // Reduce the byte-array accordingly (2b) //return String.valueOf(bufferedBlock.doFinal(decryptedBytes, processed)); // Remove return new String(decryptedBytes,"UTF-8"); // Create a UTF-8 string from the byte-array (3) |
与导入
即使这可能是遗留代码,也有两个关于安全性的注意事项:密码通常不应加密,而应加密。 此外,欧洲央行是不安全的。
这是我的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** * Step 1: password and key are converted to bytes in order to be processed by the cypher. * * Step 2: a KeyParameter is created with the key bytes. * * Step 3: a PaddedBufferedBlockCipher statement is assigned with Rijndael 256 algorithm and ZeroBytePadding, this padder adds NULL byte padding to a block. * * Step 4: the bufferedBlockCipher is then initialized with parameters"true" meaning Encryption mode, and the KeyParameter. * This initialization prepares the bufferedBlock with the parameters needed for encryption. * * Step 5: a variable"buffer" stores the length in bytes the output should have * * Step 6: the processed bytes are calculated and stored, buffer now stores the value of the password * * Step 7: the encryption is finalized, the plus equals sign ensures that the output is multiple of 32 * * Step 8: the buffer and processedBytes are converted into an array of bytes and then a String * * @param password * * @return */ public String encrypt(String password) throws InvalidCipherTextException { byte[] data = password.getBytes(); byte[] encryptionKey = key.getBytes(); KeyParameter keyParameter = new KeyParameter(encryptionKey); PaddedBufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(new RijndaelEngine(256), new ZeroBytePadding()); bufferedBlockCipher.init(true, keyParameter); byte[] buffer = new byte[bufferedBlockCipher.getOutputSize(data.length)]; int processedBytes = bufferedBlockCipher.processBytes(data, 0, data.length, buffer, 0); processedBytes += bufferedBlockCipher.doFinal(buffer, processedBytes); byte[] result = Arrays.copyOfRange(buffer, 0, processedBytes); String output = Base64.encodeBase64String(result); return output; } |