我使用以下代码在 Kotlin 中加密了一个字符串
private fun encrypt(context: Context, strToEncrypt: String, encryptKey : String): ByteArray {
val plainText = strToEncrypt.toByteArray(Charsets.UTF_8)
val key = generateKey(encryptKey)
val cipher = Cipher.getInstance("AES_256/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, key)
val cipherText = cipher.doFinal(plainText)
return cipherText
}
private fun generateKey(password: String): SecretKeySpec {
val digest: MessageDigest = MessageDigest.getInstance("SHA-256")
val bytes = password.toByteArray()
digest.update(bytes, 0, bytes.size)
val key = digest.digest()
val secretKeySpec = SecretKeySpec(key, "AES")
return secretKeySpec
}
我这样使用它:
encrypt(requireContext(), "test_string", "password")
现在我需要解密 PHP 中生成的字符串(通过 GET 接收字符串)。我有这样的东西:
function decryptString($encryptedString, $cipher, $key, $initVector) {
// decrypt and return string
return openssl_decrypt($encryptedString, $cipher, $key, 0, $initVector);
}
if (isset($_GET["plain_text"])) {
// define cipher algorithm
$cipher = "aes-256-cbc";
// generate initialization vector
$iv_size = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($iv_size);
echo decryptString($_GET["plain_text"], $cipher, "password", $iv);
}
但是结果是空的。我想这是因为在 PHP 中我可以使用一个字符串作为我定义的描述的键(
$key
过程中的 openssl_decrypt()
参数),而在 Kotlin 中(该死的 Android 总是无缘无故地过于复杂),你是被迫使用 SecretKeySpec
参数作为键,因此我无法传递硬编码字符串作为键。
我不是加密专家,所以请原谅我这个愚蠢的问题。
Kotlin 代码会自动生成一个随机 IV,您必须将其与密文一起获取并传递。将两者连接起来是很常见的,例如iv|密文。您可以使用 Base64 从字节数组生成字符串:
private fun encrypt(strToEncrypt: String, encryptKey : String): String {
val plainText = strToEncrypt.toByteArray(Charsets.UTF_8)
val key = generateKey(encryptKey)
val cipher = Cipher.getInstance("AES_256/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, key)
val cipherText = cipher.iv + cipher.doFinal(plainText) // get IV and concatenate with ciphertext
return Base64.getEncoder().encodeToString(cipherText) // Base64 encode data
}
在 PHP 方面,必须从密文中剥离 IV。此外,密钥必须像 Kotlin 代码中一样使用 SHA256 导出(顺便说一句,最好使用 PBKDF2 或更现代的 KDF):
$ivCt = base64_decode('p5ONPQVga2KWX5nM1mHI04uXRYCqFXUTYgsiIurQdfF+qidI5YOOjhn2s9g/DYuq'); // sample data from Kotlin code
$iv = substr($ivCt, 0, 16); // strip IV off
$ct = substr($ivCt, 16);
$pwd = 'your password';
$key = hash('sha256', $pwd, true); // derive key with SHA256
$dt = openssl_decrypt($ct, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); // disable default Base64 with OPENSSL_RAW_DATA
print($dt . PHP_EOL); // Take me to your leader