Android中对应于PHP中的AES-256-CBC-HMAC-SHA256的加密方式是什么?

huangapple go评论72阅读模式
英文:

Android equivalent to AES-256-CBC-HMAC-SHA256 in PHP

问题

以下是您要翻译的部分:

我在PHP中进行了以下加密:

openssl_encrypt( $data, "AES-256-CBC-HMAC-SHA256", $key, OPENSSL_RAW_DATA, $iv ) );

我需要在我的Android应用程序中以JSON格式接收$data。

我需要在应用程序中解密$data。

我正在使用以下结构:

    private static final String engine = "AES";
    private static final String crypto = "AES/CBC/PKCS5Padding";
    [...]

    public byte[] cipher(byte[] data, int mode, String key, String iv2) throws NoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidAlgorithmParameterException {        
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), engine);
        IvParameterSpec iv = new IvParameterSpec(iv2.getBytes());
        Cipher c = Cipher.getInstance(crypto);
        c.init(mode, sks, iv);
        return c.doFinal(data);
    }

    public byte[] decrypt(byte[] data,  String key, String iv) throws InvalidKeyException,
            NoSuchAlgorithmException, NoSuchPaddingException,
            IllegalBlockSizeException, BadPaddingException,
            InvalidAlgorithmParameterException {
        return cipher(data, Cipher.DECRYPT_MODE,key,iv);
    }

但将engine定义为"AES"和crypto定义为"AES/CBC/PKCS5Padding"会引发错误,因为它与服务器端的加密不等效。

另一方面,使用具有该密码函数的加密函数,然后解密它确实有效,因为加密和解密都使用相同的密钥、IV、engine和crypto完成。

对于PHP中的AES-256-CBC-HMAC-SHA256,哪个是等效的engine和crypto呢?
英文:

I've the following encryption done in PHP:

openssl_encrypt( $data, "AES-256-CBC-HMAC-SHA256", $key, OPENSSL_RAW_DATA, $iv ) );

I get to receive that $data in a JSON in my Android app.

I've to decrypt that $data in the app.

I'm using an structure like the following:

private static final String engine = "AES";
private static final String crypto = "AES/CBC/PKCS5Padding";
[...]

public byte[] cipher(byte[] data, int mode, String key, String iv2) throws NoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidAlgorithmParameterException {        
    SecretKeySpec sks = new SecretKeySpec(key.getBytes(), engine);
    IvParameterSpec iv = new IvParameterSpec(iv2.getBytes());
    Cipher c = Cipher.getInstance(crypto);
    c.init(mode, sks, iv);
    return c.doFinal(data);
}

public byte[] decrypt(byte[] data,  String key, String iv) throws InvalidKeyException,
        NoSuchAlgorithmException, NoSuchPaddingException,
        IllegalBlockSizeException, BadPaddingException,
        InvalidAlgorithmParameterException {
    return cipher(data, Cipher.DECRYPT_MODE,key,iv);
}

So I call decrypt with the required key and the required iv.

But defining engine as "AES" and crypto as "AES/CBC/PKCS5Padding" throws an error, because it's not equivalent to the one from the server.

On the other hand, using an encrypt function with that cipher function and later decrypting it does work, as either the encryption and the decryption are done with the same key, iv, engine and crypto.

Which would be the engine and crypto equivalent for that AES-256-CBC-HMAC-SHA256 in PHP?

答案1

得分: 2

我正在回答你的问题,但我感到困惑...你会看到 :-).

首先,我使用了两个加密/解密函数来设置一个简单的PHP程序,它们使用以下算法:

$algorithm = "aes-256-cbc-hmac-sha256";
$algorithm2 = "aes-256-cbc";

代码:

<?php
// https://stackoverflow.com/questions/63135041/android-equivalent-to-aes-256-cbc-hmac-sha256-in-php
$key = "!mysecretkey#9^5usdk39d&dlf)03sL";
$iv = "Cfq84/46Qjet3EEQ1HUwSg==";
$plaintext = "The quick brown fox jumps over the lazy dog";

$algorithm = "aes-256-cbc-hmac-sha256";
echo 'encryption with algorithm: ' . $algorithm . PHP_EOL;
// encryption
$ciphertext = openssl_encrypt($plaintext, $algorithm, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo 'ciphertext : ' . base64_encode($ciphertext) . PHP_EOL;
// decryption
$decryptedtext = openssl_decrypt($ciphertext, $algorithm, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo 'cbc-256-hmac decrypt : ' . $decryptedtext . PHP_EOL . PHP_EOL;

$algorithm2 = "aes-256-cbc";
echo 'encryption with algorithm: ' . $algorithm2 . PHP_EOL;
$ciphertext2 = openssl_encrypt($plaintext, $algorithm2, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo 'ciphertext2: ' . base64_encode($ciphertext2) . PHP_EOL;
// decryption
$decryptedtext2 = openssl_decrypt($ciphertext2, $algorithm2, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo 'cbc-256 decrypt      : ' . $decryptedtext2 . PHP_EOL;
?>

两者都可以正常工作,但让我困惑的是它们产生了相同的输出(这里以Base64编码表示):

encryption with algorithm: aes-256-cbc-hmac-sha256
ciphertext : sdFQ/X0YdAlyTe8ICtQSb3aHRGzsAdyXRlUGdocGZS9sckqa2seeYaVD10vYu5wV
cbc-256-hmac decrypt : The quick brown fox jumps over the lazy dog

encryption with algorithm: aes-256-cbc
ciphertext2: sdFQ/X0YdAlyTe8ICtQSb3aHRGzsAdyXRlUGdocGZS9sckqa2seeYaVD10vYu5wV
cbc-256 decrypt      : The quick brown fox jumps over the lazy dog

将密文字符串作为输入,使用以下算法的简单Java解密方法:

AES/CBC/PKCS5Padding

加密的消息成功解密。因此,也许我们的某位“加密大师”能够解释为什么两种不同的算法产生了相同的输出。

以下是Java的结果:

decryptedtext: The quick brown fox jumps over the lazy dog

以及Java代码:

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class Main {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        System.out.println("https://stackoverflow.com/questions/63135041/android-equivalent-to-aes-256-cbc-hmac-sha256-in-php");

        String key = "!mysecretkey#9^5usdk39d&dlf)03sL";
        String iv = "Cfq84/46Qjet3EEQ1HUwSg==";
        String ciphertext = "sdFQ/X0YdAlyTe8ICtQSb3aHRGzsAdyXRlUGdocGZS9sckqa2seeYaVD10vYu5wV";

        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(Base64.getDecoder().decode(iv));
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] decryptedtextByte = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
        String decryptedtext = new String(decryptedtextByte);
        System.out.println("decryptedtext: " + decryptedtext);
    }
}
英文:

I'm answering your question but I'm confused... you will see :-).

First I setup a simple PHP program with 2 en-/decryption functions, they are using the following algorithms:

$algorithm = &quot;aes-256-cbc-hmac-sha256&quot;;
$algorithm2 = &quot;aes-256-cbc&quot;;

code:

&lt;?php
// https://stackoverflow.com/questions/63135041/android-equivalent-to-aes-256-cbc-hmac-sha256-in-php
$key = &quot;!mysecretkey#9^5usdk39d&amp;dlf)03sL&quot;;
$iv = &quot;Cfq84/46Qjet3EEQ1HUwSg==&quot;;
$plaintext = &quot;The quick brown fox jumps over the lazy dog&quot;;

$algorithm = &quot;aes-256-cbc-hmac-sha256&quot;;
echo &#39;encryption with algorithm: &#39; . $algorithm . PHP_EOL;
// encryption
$ciphertext = openssl_encrypt($plaintext, $algorithm, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo &#39;ciphertext : &#39; . base64_encode($ciphertext) . PHP_EOL;
// decryption
$decryptedtext = openssl_decrypt($ciphertext, $algorithm, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo &#39;cbc-256-hmac decrypt : &#39; . $decryptedtext . PHP_EOL . PHP_EOL;

$algorithm2 = &quot;aes-256-cbc&quot;;
echo &#39;encryption with algorithm: &#39; . $algorithm2 . PHP_EOL;
$ciphertext2 = openssl_encrypt($plaintext, $algorithm2, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo &#39;ciphertext2: &#39; . base64_encode($ciphertext2) . PHP_EOL;
// decryption
$decryptedtext2 = openssl_decrypt($ciphertext2, $algorithm2, $key, $options = OPENSSL_RAW_DATA, base64_decode($iv));
echo &#39;cbc-256 decrypt      : &#39; . $decryptedtext2 . PHP_EOL;
?&gt;

Both do fine but - that's what is confusing me - give the same output (here encoded in Base64):

encryption with algorithm: aes-256-cbc-hmac-sha256
ciphertext : sdFQ/X0YdAlyTe8ICtQSb3aHRGzsAdyXRlUGdocGZS9sckqa2seeYaVD10vYu5wV
cbc-256-hmac decrypt : The quick brown fox jumps over the lazy dog

encryption with algorithm: aes-256-cbc
ciphertext2: sdFQ/X0YdAlyTe8ICtQSb3aHRGzsAdyXRlUGdocGZS9sckqa2seeYaVD10vYu5wV
cbc-256 decrypt      : The quick brown fox jumps over the lazy dog

Using the ciphertext string as input in a simple Java decryption method using the algorithm

AES/CBC/PKCS5Padding

the encrypted message get decrypted successfully. So maybe one of our "crypto-gurus" is been able to "put on the spot" why two different algorithms gave the same output.

Here is the Java-result:

decryptedtext: The quick brown fox jumps over the lazy dog

and the Java code:

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class Main {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        System.out.println(&quot;https://stackoverflow.com/questions/63135041/android-equivalent-to-aes-256-cbc-hmac-sha256-in-php&quot;);

        String key = &quot;!mysecretkey#9^5usdk39d&amp;dlf)03sL&quot;;
        String iv = &quot;Cfq84/46Qjet3EEQ1HUwSg==&quot;;
        String ciphertext = &quot;sdFQ/X0YdAlyTe8ICtQSb3aHRGzsAdyXRlUGdocGZS9sckqa2seeYaVD10vYu5wV&quot;;

        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), &quot;AES&quot;);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(Base64.getDecoder().decode(iv));
        Cipher cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5Padding&quot;);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] decryptedtextByte = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
        String decryptedtext = new String(decryptedtextByte);
        System.out.println(&quot;decryptedtext: &quot; + decryptedtext);
    }
}

huangapple
  • 本文由 发表于 2020年7月28日 21:16:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63135041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定