微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何用编程语言解密notepad ++ nppcrypt加密消息

如何解决如何用编程语言解密notepad ++ nppcrypt加密消息

纯文本:你好莱昂

密码和iv:leon1234leon1234

密码:rijndael cbc 128bits

nppcrypto 加密信息

<nppcrypt version="1016">
<encryption cipher="rijndael" key-length="16" mode="cbc" encoding="base64" />
<key algorithm="scrypt" N="16384" r="8" p="1" salt="HA==" />
<iv value="bGVvbjEyMzRsZW9uMTIzNA==" method="custom" />
</nppcrypt>
/8r4DGLVYC+YJSPMFQ8lFQ==

我用java BouncyCastle lib测试,但是加密结果不一样

相关代码在我的github仓库

https://github.com/Leon406/Crypto/blob/master/src/main/kotlin/me/leon/modern/PBE.kt

nppcrypt 插件仓库:https://github.com/jeanpaulrichter/nppcrypt

编辑:这里也有代码

package me.leon.modern

import com.lambdaworks.crypto.SCryptUtil
import me.leon.base64Decode
import me.leon.toBase64
import org.bouncycastle.crypto.generators.BCrypt
import org.bouncycastle.crypto.generators.KDF2BytesGenerator
import org.bouncycastle.crypto.generators.SCrypt
import org.bouncycastle.util.encoders.Hex

/**
 *
 *
 * https://www.bouncycastle.org/specifications.html
 * https://antofthy.gitlab.io/info/crypto/key_derivation.txt
 * https://www.openssl.org/docs/manmaster/man1/openssl-kdf.html
 * key derivation function
 * SCrypt   BCrypt  PBKDF2    Added in OpenSSL 3.0
 * Question? how to interact notepad++ nppcrypto
 */
object PBE {
    @JvmStatic
    fun main(args: Array<String>) {
        val pwd = "leon1234leon1234"
        val salt = "HA=="
        val ivbase64 = "leon1234leon1234"
        val key = SCrypt.generate(pwd.toByteArray(),salt.base64Decode(),16384,8,1,16).toBase64()
        val key2 = BCrypt.generate(pwd.toByteArray(),"iP/MuFEP/jgHs7lBGez7kg==".base64Decode(),8).toBase64()
        println(key)

        SCryptUtil.scrypt(pwd,1).also {
            println("scrypt $it")
        }
        //$s0$e0801$YzXui6dcQ0qbWnTBP36t+Q==$AW81b69h3HepUIi7pW7ThAKuDdpb1oZ7bFIJrF9zQzA=
        //$s0$e0801$bGvjR0//WiaHqAiSDi5Q9g==$8DzAr+nhUyW5fhdj3MLIpovRdp+dLfVoXGqN+Pp3kZU=
         SCrypt.generate(pwd.toByteArray(),"YzXui6dcQ0qbWnTBP36t+Q==".base64Decode(),32).toBase64().also {
             println("scrypt dd $it" )
         }
        val r = SymmetricCrypto.encrypt(key,"Hello leon",ivbase64,"AES/CBC/PKCS5Padding")
            .also { println(it) }
        val r2 = SymmetricCrypto.encrypt(key2,"AES/CBC/PKCS5Padding")
            .also { println(it) }

        SymmetricCrypto.decrypt(key,r,"AES/CBC/PKCS5Padding").also { println(it) }
        SymmetricCrypto.decrypt(key2,r2,"AES/CBC/PKCS5Padding").also { println(it) }
    }
}

解决方法

您将密钥传递给 SymmetricCrypto.decrypt() Base64 编码,但您不在那里执行 Base64 解码,而是执行 UTF8 编码,s。 here。因此解密失败。

通常 key 和 IV 是二进制数据而不是字符串。因此,两者都应在 ByteArray 中作为 encrypt()/decrypt() 传递。如果要将它们作为字符串传递,则必须执行可靠的二进制到文本编码,例如 Base64。

以下修复使用第二个变体,即传递给 decrypt() Base64 编码的密钥,并在那里进行 IV 和 Base64 解码:

import org.bouncycastle.crypto.generators.SCrypt
import org.bouncycastle.jce.provider.BouncyCastleProvider
import java.security.Security
import java.util.*
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
...
val pwd = "leon1234leon1234"
val salt = "HA=="
val key = SCrypt.generate(pwd.toByteArray(),salt.base64Decode(),16384,8,1,16).toBase64().also { println(it) } // 6owLoTdeL67pEHxJ5gLY9Q==
val iv = "bGVvbjEyMzRsZW9uMTIzNA=="
val ciphertext = "/8r4DGLVYC+YJSPMFQ8lFQ=="
/*SymmetricCrypto.*/decrypt(key,ciphertext,iv,"AES/CBC/PKCS5Padding").also { println(it) } // Hello leon
...
fun decrypt(key: String,data: String,iv: String,alg: String): String {
    val cipher = Cipher.getInstance(alg)
    val keySpec: SecretKey = SecretKeySpec(key.base64Decode()/*toByteArray()*/,alg.substringBefore("/")) // pass key Base64 encoded and Base64 decode here
    if (alg.contains("ECB".toRegex()))
        cipher.init(Cipher.DECRYPT_MODE,keySpec)
    else
        cipher.init(Cipher.DECRYPT_MODE,keySpec,IvParameterSpec(iv.base64Decode()/*toByteArray()*/)) // pass iv Base64 encoded and Base64 decode here
    return String(cipher.doFinal(Base64.getDecoder().decode(data)))
}

关于安全的一些注意事项:

  • 静态 IV 不安全。 nppcrypt 支持随机 IV。 IV 不应与密码相同。
  • 1 字节的盐太短了。
  • ECB 是不安全的(只是为了完整性,因为在发布的示例中没有使用 ECB,但已实施)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。