C#BouncyCastle-使用公钥/私钥进行RSA加密

刺客

我需要使用C#加密数据才能将其传递给Java。Java代码属于第三方,但已经获得了相关的消息来源,因此我决定,由于Java使用Bouncy Castle库,因此我将使用C#端口。

解密工作正常。但是,只有当我使用私钥而不是公钥使用加密时,解密才有效。使用公钥时,解密失败unknown block type

显然,加密时RsaEncryptWithPrivate使用内部密钥进行加密,因此我不明白为什么两种加密方法在功能上不相同:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.OpenSsl;

public class EncryptionClass
{       
    public string RsaEncryptWithPublic(string clearText
        , string publicKey)
    {
        var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);

        var encryptEngine = new Pkcs1Encoding(new RsaEngine());

        using (var txtreader = new StringReader(publicKey))
        {
            var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();

            encryptEngine.Init(true, keyParameter);
        }

        var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
        return encrypted;

    }

    public string RsaEncryptWithPrivate(string clearText
        , string privateKey)
    {
        var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);

        var encryptEngine = new Pkcs1Encoding(new RsaEngine());

        using (var txtreader = new StringReader(privateKey))
        {
            var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();

            encryptEngine.Init(true, keyPair.Public);
        }

        var encrypted= Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
        return encrypted;
    }


    // Decryption:

    public string RsaDecrypt(string base64Input
        , string privateKey)
    {
        var bytesToDecrypt = Convert.FromBase64String(base64Input);

        //get a stream from the string
        AsymmetricCipherKeyPair keyPair;
        var decryptEngine = new Pkcs1Encoding(new RsaEngine());

        using ( var txtreader = new StringReader(privateKey) )
        {
            keyPair = (AsymmetricCipherKeyPair) new PemReader(txtreader).ReadObject();

            decryptEngine.Init(false, keyPair.Private);
        }

        var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
        return decrypted;
    }
}

// In my test project   

    [Test()]
    public void EncryptTest()
    {
        // Set up 
        var input = "Perceived determine departure explained no forfeited";
        var enc = new EncryptionClass();
        var publicKey = "-----BEGIN PUBLIC KEY----- // SNIPPED // -----END PUBLIC KEY-----";
        var privateKey = "-----BEGIN PRIVATE KEY----- // SNIPPED // -----END PRIVATE KEY-----";

        // Encrypt it
        var encryptedWithPublic = enc.RsaEncryptWithPublic(input, publicKey); 

        var encryptedWithPrivate = enc.RsaEncryptWithPrivate(input, privateKey);

        // Decrypt
        var outputWithPublic = payUEnc.RsaDecrypt(encryptedWithPrivate, privateKey); 
        // Throws error: "unknown block type"

        var outputWithPrivate = payUEnc.RsaDecrypt(encryptedWithPrivate, _privateKey); 
        // returns the correct decrypted text, "Perceived determine departure explained no forfeited"

        // Assertion
        Assert.AreEqual(outputWithPrivate, input); // This is true
    }

顺便说一下,Java解密也存在相同的问题-仅用公共密钥加密时,它会失败。

我是密码技术的新手,所以我确定我在该RsaEncryptWithPublic方法中犯了一些非常简单的错误

编辑:

我还添加了一个单元测试,以证明公钥等于从私钥中提取的公钥:

    [Test()]
    public void EncryptCompareTest()
    {
        AsymmetricKeyParameter keyParameterFromPub;
        AsymmetricKeyParameter keyParameterFromPriv;
        AsymmetricCipherKeyPair keyPair;

        using (var txtreader = new StringReader(_publicKey))
        {
            keyParameterFromPub = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();
        }

        using (var txtreader = new StringReader(_privateKey))
        {
            keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
            keyParameterFromPriv = keyPair.Public;
        }

        Assert.AreEqual(keyParameterFromPub, keyParameterFromPriv); // returns true;

    } 
刺客

我使用了不正确的公钥。.证明私钥和公钥匹配的测试使用的是正确的公钥。

只要您正确输入密钥,上面的代码就可以完美地工作!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在C#RSA中使用私钥加密和使用公钥解密

使用nodeJS和Objective-C的非对称公钥/私钥加密RSA

如何在C#中使用公钥加密密码并在私钥中解密私钥

使用来自 X509 证书 C++ 的公钥的 RSA 公共加密

使用IOS进行公钥加密和使用C#进行解密

如何使用BouncyCastle C#将RSA公钥转换为字符串

反序列化RSA公钥和私钥C#

如何使用OpenSSL EVP例程进行RSA公钥加密?

使用OpenSSL生成RSA公钥/私钥?

使用RSA私钥生成公钥?

Python加密,RSA公钥/私钥,带有大文件

使用RSA-2048服务器公钥加密客户端私钥

非对称加密算法,允许使用公钥和私钥进行加密和解密

如何将Java RSA公钥移植到C#加密功能?

在C#中通过JS发行解密RSA公钥加密数据的问题

无法在C#bouncycastle和PHP openssl之间交换AES-256-CBC / PKCS7

使用RSA公钥加密AES密钥

对使用公钥和私钥加密(用于加密)感到困惑

生成RSA公钥/私钥对

公钥/私钥对AES会话密钥进行加密

RSACryptoServiceProvider使用自己的公钥和私钥进行加密和解密

如何使用在 Hyperledger Fabric 中生成的 ECDSA 私钥和公钥进行加密和解密

RSA加密-公钥加密

(C#) 在 (EC)DHE x25519 上使用私钥和公钥计算密钥份额

如何在Ruby中使用PKI(公钥/私钥)加密?

使用RSA公钥在Openssl中生成私钥?

Azure Key Vault - 检索 RSA 公钥以进行本地加密

RSA在Android中使用base64编码的公钥进行加密

iOS:使用公钥(具有模数和指数)进行RSA加密