我有两个小的Kotlin例程用于加密和解密。但我想有第二个工具(openssl)解密以及,只是为了保存...我的问题它不工作。
import java.nio.charset.StandardCharsets
import java.util.*
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
class Main2(private val args: Array<String>) {
public fun encrypt(plaintext: String, password: String): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") // From Env
val keySpec = SecretKeySpec(password.toByteArray(StandardCharsets.UTF_8), "AES")
val iv = IvParameterSpec(ByteArray(16))
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv)
val encryptedBytes = cipher.doFinal(plaintext.toByteArray(StandardCharsets.UTF_8))
return Base64.getEncoder().encodeToString(encryptedBytes)
}
public fun decrypt(ciphertext: String, password: String): String {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val keySpec = SecretKeySpec(password.toByteArray(StandardCharsets.UTF_8), "AES")
val iv = IvParameterSpec(ByteArray(16))
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv)
val decodedBytes = Base64.getDecoder().decode(ciphertext)
val decryptedBytes = cipher.doFinal(decodedBytes)
return String(decryptedBytes, StandardCharsets.UTF_8)
}
fun main() {
val plainText = "hello world"
val password = "ThisIsMySuperSecretPassword77788"
val cipherText = encrypt(plainText, password)
val decryptedText = decrypt(cipherText, password)
println("Original Text: $plainText")
println("Encrypted Text: $cipherText")
println("Decrypted Text: $decryptedText")
}
}
fun main(args: Array<String>) {
Main2(args).main()
}
这是我用来解密消息的调用:
openssl enc -d -aes-256-cbc -base64 -in encrypted.txt -out decrypted.txt -pass pass:ThisIsMySuperSecretPassword77788
应该也可以使用openssl来decrpyt。我已经问过chatgpt了,但是没有用。
1条答案
按热度按时间bvhaajcl1#
在Kotlin代码中,密钥材料被 * 直接 * 作为密钥与静态IV(16个0x 00值)一起应用。
相反,在OpenSSL语句中,密钥材料用作密码,使用密钥派生函数(
EVP_BytesToKey()
)从该密码 * 派生 * 密钥和IV。为了能够使用OpenSSL语句解密Kotlin代码的密文,因此还必须在OpenSSL语句中直接指定key和IV。为此,使用-K和-iv选项。数据必须指定为十六进制编码。
对于Base64编码,如果所有数据都要在一行上处理,则必须另外设置-A选项。
使用以下OpenSSL语句解密成功:
请注意,静态IV是一个漏洞。相反,应该为每个加密生成一个随机IV,并将其与密文沿着传递给解密端,通常是串联的(IV不是秘密的)。
此外,密钥应该是所需长度的随机字节序列(对于AES-256为32字节),而不是字符串。如果您真的想使用字符串作为密钥材料,那么请与Argon 2或至少PBKDF 2等密钥派生函数结合使用(不应使用专有的OpenSSL函数
EVP_BytesToKey()
,因为它已被弃用并被视为不安全)。