【问题标题】:AES Encryption Android / AES Decryption PHPAES 加密 Android / AES 解密 PHP
【发布时间】:2016-09-22 23:37:52
【问题描述】:

我正在尝试在 Android 和 PHP 端使用 AES 加密/解密数据并收到空答案。

首先,我在 Android 中生成了对称密钥:

public static  SecretKeySpec generateSymmetric() {

    // Set up secret key spec for 128-bit AES encryption and decryption
    SecretKeySpec sks = null;
    try {
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed("any data used as random seed".getBytes());
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        kg.init(128, sr);
        sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

        System.out.println("AES KEY: " + sks);
    } catch (Exception e) {
        Log.e(TAG, "AES secret key spec error");
    }
    return sks;
}

然后我将 SecretKeySpec 转换为 Base64 字符串格式:

public static String ConvertSymmetricKeyToString(SecretKeySpec key) {

    String symmetric_key = null;

    symmetric_key = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
    return symmetric_key;
}

调用函数:

    SecretKeySpec symmKey = generateSymmetric();


    newSymmetricKeyString = CreateEncryptedXml.ConvertSymmetricKeyToString(symmKey);

然后我使用 SecretKeySpec 加密数据:

    private static String encryptDataWithSymmetricKey (SecretKeySpec symmKey, String data) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {


    // encryption
    byte[] toBeCiphred = data.getBytes("UTF-8");
    String encryptedData = null;

    try {
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, symmKey);
        byte[] encodedBytes = c.doFinal(toBeCiphred);
        System.out.println("BYTE STRING (ASYMM): " + encodedBytes);
        encryptedData = Base64.encodeToString(encodedBytes, Base64.DEFAULT);

    } catch (Exception e) {
        Log.e(TAG, "AES encryption error");
        throw new RuntimeException(e);
    }


    return encryptedData;
}
    encryptedData = encryptDataWithSymmetricKey(symmKey, text);

然后我在 XML 中打包字符串秘密 AES 密钥和加密数据(使用此 AES 密钥加密),并使用 okhttp 向 php 服务器发出 POST 请求。字符串密钥使用 RSA 加密。

在服务器端,我尝试解密数据。我可以解密(来自 RSA)秘密 AES 密钥并获得它的字符串表示形式。在客户端(Android)和服务器端(PHP)上是一样的。但是如何使用这个字符串 AES 密钥解密数据?我试过这个(PHP):

   $encryptionMethod = "AES-128-CBC";  

  //$decryptedAESKey is an Android AES SecretKeySpec converted  to string
  //in Android the string key was base64_encoded, so i decode it
  $secretHash = base64_decode($decryptedAESKey);


 // Decrypt
  $decryptedMessage = openssl_decrypt(base64_decode($encryptedData),  $encryptionMethod, $secretHash);

  //Result
  echo "Encrypted: $encryptedData   ";
  echo " Decrypted: $decryptedMessage";

php 中的结果:

Encrypted:      s/00eZdv6sMq1hIgPUMMknb1w8d03t+R5KHn5FkHqhNJyDlBZlbm8t+t4RWh9tg/7LD9R2VbihGG
                                                                 Boz9ydMEszYGgTanE2TII+OOSFZIYgCU7ekKkRLax+F2yoMvSB52LDxQ9b9ZOTxy0Zn+hH6jbVdl
                                                               HVffbk+DJTJ1PVgeRfTaG4yC6cmXh5oFx7vDxM2u+8FWc3rNTt9zKUiu0FGLn3pWpA4wyCZfoCnA
                                                               rSJWrtaPLWxPEqipJCafTc1wRof9PqkDmIQJLOr84FpsnhH0JqjwXRmyDp5K8jKe+UzvE/B1B5Sj
                                                               QiTgK1Z2wPXzQClXimX2U9AQYc33FsYQMATHNw==
                                                                   Decrypted: 

怎么了?

【问题讨论】:

  • 当寻求帮助时,一个小例子很有帮助,这将包括键、短数据、iv、模式和输出。
  • 欢迎来到 Stack Overflow!一般建议:始终使用完全限定的密码字符串。 Cipher.getInstance("AES"); 可能会产生不同的密码,具体取决于默认的安全提供程序。它最有可能导致"AES/ECB/PKCS5Padding",但并非必须如此。如果它发生变化,您将失去不同 JVM 之间的兼容性。
  • 切勿使用ECB mode。它是确定性的,因此在语义上不安全。您至少应该使用像CBCCTR 这样的随机模式。最好对您的密文进行身份验证,以免像padding oracle attack 这样的攻击是不可能的。这可以通过 GCM 或 EAX 等认证模式或encrypt-then-MAC 方案来完成。

标签: php android encryption aes rsa


【解决方案1】:

使用 CBC 模式时,需要代码中缺少的块大小(AES 为 16 字节)iv(初始化向量)。也不清楚ENCRYPT_MODE在Android代码中是什么。

【讨论】:

  • ENCRYPT_MODE 也很重要。如果是 AES/CBC/PKCS5Padding,那么 OpenSSL 可能会假设一个填充错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
  • 2018-08-16
相关资源
最近更新 更多