gpt4 book ai didi

java - 将 PHP Rijndael 算法重写为 Java (Android)

转载 作者:太空狗 更新时间:2023-10-29 12:39:50 24 4
gpt4 key购买 nike

我需要在 Java 和 php 中对字符串进行编码,结果必须相同。

给出以下条件:

  1. 算法:RIJNDAEL-128
  2. key :5P443m2Q1R9A7f5r3e1z08642
  3. 模式:欧洲央行
  4. 初始化 vector :N/A(因为我们使用的是 ECB,IV 被忽略)

要编码的字符串: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, $this->securekey, base64_decode($input), MCRYPT_MODE_ECB, $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, 0, keyBytes, 0, 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, keyBytes), characterEncoding);
}

}

输出:wd0FHYpLbgdpHhcSql7VVCiKWJWN5hvP0W9F4sgKWAWeDcSjvfKWTM5LHBCZJSRw

更新:

我将填充从 NoPadding 更改为 PKCS5Padding

这是正确的吗?我不确定,因为如果您查看 PHP 代码。没有指定任何填充(我自己基于语法的假设)。

Info on Mcrypt

额外见解:

阅读此 document关于填充(无填充)。一定与问题有关。

最佳答案

看起来您的 PHP 版本使用 AES-128,根据定义,它使用 128 位(16 字节) key 。但是看起来您传递了一个 25 字节的 key (5P443m2Q1R9A7f5r3e1z08642),我不确定发生这种情况时 PHP 会做什么。

您的 Java 版本的 getKeyBytes() 方法仅返回所提供 key 的前 16 个字节,因此它仅使用该字节进行加密。

尝试将您的 PHP 版本中的 key 截断为 5P443m2Q1R9A7f5r,您会得到相同的结果。除了可能不同的结束部分。那时,问题就是填充。您可以对明文应用 pkcs5_pad PHP 函数,使其与您的 Java 版本相匹配。

综上所述,如果这只是为了学习目的,那没关系。否则,对于实际使用,您很重要 do not use ECB cipher mode .

关于java - 将 PHP Rijndael 算法重写为 Java (Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27921093/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com