使用Bouncy Castle RSA加解密密码时遇block incorrect错误
RSA解密报错"block incorrect"的解决方案
注意:请勿使用此方法加密用户密码。应使用哈希算法存储用户密码,还可类似Salt Bae的方式为密码添加盐值。
我需要存储一个用于程序登录的密码,加密操作可正常完成,但解密时出现以下错误:Org.BouncyCastle.Crypto.InvalidCipherTextException: 'block incorrect'
后续会更换私钥,因此无需担心当前私钥泄露问题。
程序类代码
var input = "TestPassword123!"; Encryption EC = new Encryption(); var Key = "-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQCr874y+f3cYtz8hOuxamwHYUK7WS03c3t7LHMuCpmiR9wOz1FHEbBk6ZdvhY74I9sE+lIs0bUZVh08nKIS/txeECZ/d3WYDm8gW+mFjg0xD7LgQ9Prchsvrb2Q9c6FK5Us8i0iqOhDmrZdCYO+/zhyrYnP/Wy1EZTWPvMrI/GVWwIDAQABAoGBAJW5Sg8HIKYKq5NxhezY1rHiXYHWV4nmE0ogXTZk4nusiI+Ys5PncimcQFFKAUBNsEL4WB9QhplGI3UIihNyOZx68waSB6NiAi+tz8i7edTxDfwWkM271roOJxD3RzUJuQkyc57ZxrD61UyodRatmRoJkPhLBlEvIr9/dCwYBl0pAkEA5ucK8CFdxr4DWIAutZLeeeQx9oe1tCi/iUvEpSDOHKAvaELLBiD4bIInN4nx/Gj1gwHqICg8L/gs0x23cQWz3QJBAL6kYaRQFvCmVajTaTJ3ef3gYwynPsmfT5Urx0DWW5rXtbtZQ7vScDKRU4YbmBb3tD5eT/Fl/dIakPGv+hxllpcCQA3o5TPKDsgmMjVmo2m0y0o0gP4E9uE/gypWMiZwb3ox/CkfvPNFkTGYNZyW5sj52bBmsR/2zIlnPewJ4j8gxNECQDOT/8LX1E0Jg5VolUaNIpk4UzQCL6+XBY4DSSZWmHQdNlLYxMWVGrvjq6hV4OEd5UsWcySJhpGIlHx/Mvjp10MCQAon0SLhRI8QNrWfp/dLuFdqTy4b4y64j3HvooOu6GDZwCLwjqvwML3rimxUi52EQspssIOlLjpQjvIJvYBKBys=-----END RSA PRIVATE KEY-----"; var encrypted = EC.RsaEncrypt(input, Key); string password = EC.RsaDecrypt(encrypted, Key);
加密类代码
using System; using System.IO; using System.Text; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.OpenSsl; namespace TemarkNamespace { internal class Encryption { public string RsaEncrypt(string clearText, string Key) { var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText); var encryptEngine = new Pkcs1Encoding(new RsaEngine()); using (var txtreader = new StringReader(Key)) { var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); encryptEngine.Init(true, keyPair.Private); } var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length)); return encrypted; } // Decryption: public string RsaDecrypt(string pass, string Key) { var bytesToDecrypt = Convert.FromBase64String(pass); AsymmetricCipherKeyPair keyPair; var decryptEngine = new Pkcs1Encoding(new RsaEngine()); using (var txtreader = new StringReader(Key)) { keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); decryptEngine.Init(false, keyPair.Private); } var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length)); return decrypted; } } }
问题原因
你犯了RSA使用的核心错误:加密应该用公钥,解密用私钥。当前代码中加密和解密都使用了私钥,虽然用私钥"加密"本质是签名操作,但PKCS#1编码的解密逻辑会验证密文格式,导致抛出"block incorrect"错误。
修复方案
修改RsaEncrypt方法,初始化加密引擎时使用公钥(keyPair.Public)而非私钥:
public string RsaEncrypt(string clearText, string Key) { var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText); var encryptEngine = new Pkcs1Encoding(new RsaEngine()); using (var txtreader = new StringReader(Key)) { var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject(); // 替换为使用公钥初始化加密引擎 encryptEngine.Init(true, keyPair.Public); } var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length)); return encrypted; }
修改后,加密用公钥,解密用私钥,即可正常完成加解密流程。
内容的提问来源于stack exchange,提问作者Meneghini
相关产品推荐
相关产品推荐

