使用Kotlin和openssl解密

bkhjykvo  于 2023-03-30  发布在  Kotlin
关注(0)|答案(1)|浏览(200)

我有两个小的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了,但是没有用。

bvhaajcl

bvhaajcl1#

在Kotlin代码中,密钥材料被 * 直接 * 作为密钥与静态IV(16个0x 00值)一起应用。
相反,在OpenSSL语句中,密钥材料用作密码,使用密钥派生函数(EVP_BytesToKey())从该密码 * 派生 * 密钥和IV。
为了能够使用OpenSSL语句解密Kotlin代码的密文,因此还必须在OpenSSL语句中直接指定key和IV。为此,使用-K和-iv选项。数据必须指定为十六进制编码。
对于Base64编码,如果所有数据都要在一行上处理,则必须另外设置-A选项。
使用以下OpenSSL语句解密成功:

openssl enc -d -aes-256-cbc -base64 -A -in encrypted.txt -out decrypted.txt -K 5468697349734d79537570657253656372657450617373776f72643737373838 -iv 00000000000000000000000000000000

请注意,静态IV是一个漏洞。相反,应该为每个加密生成一个随机IV,并将其与密文沿着传递给解密端,通常是串联的(IV不是秘密的)。
此外,密钥应该是所需长度的随机字节序列(对于AES-256为32字节),而不是字符串。如果您真的想使用字符串作为密钥材料,那么请与Argon 2或至少PBKDF 2等密钥派生函数结合使用(不应使用专有的OpenSSL函数EVP_BytesToKey(),因为它已被弃用并被视为不安全)。

相关问题