如何用编程语言解密记事本++ nppcrypt加密消息
Posted
技术标签:
【中文标题】如何用编程语言解密记事本++ nppcrypt加密消息【英文标题】:How to decrypt notepad++ nppcrypt encrypted message in programming language 【发布时间】:2021-08-28 01:25:41 【问题描述】:纯文本:你好莱昂
密码 & 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" s />
<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,16384,8,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(), 16384, 8, 1, 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, "Hello leon", ivbase64, "AES/CBC/PKCS5Padding")
.also println(it)
SymmetricCrypto.decrypt(key, r, ivbase64, "AES/CBC/PKCS5Padding").also println(it)
SymmetricCrypto.decrypt(key2, r2, ivbase64, "AES/CBC/PKCS5Padding").also println(it)
【问题讨论】:
【参考方案1】:您将密钥传递给SymmetricCrypto.decrypt()
Base64 编码,但您不在那里执行 Base64 解码,而是执行 UTF8 编码,s。 here。因此解密失败。
通常 key 和 IV 是二进制数据而不是字符串。因此,两者都应该在encrypt()/decrypt()
中作为ByteArray
传递。如果要将它们作为字符串传递,则必须执行可靠的二进制到文本编码,例如 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,但已实施)。【讨论】:
我写的demo可以解密成功。问题是为什么答案和notepad++插件加密不一样 忘记改ivbase64名字了,不是base64编码的,确实误导了你以上是关于如何用编程语言解密记事本++ nppcrypt加密消息的主要内容,如果未能解决你的问题,请参考以下文章
如何用另一种语言解密由 Ruby 的“对称加密”gem 加密的数据?