C#(.NET)RSACryptServiceProvider导入/导出x509公钥blob和PKCS8私钥blob

C#(.NET)RSACryptServiceProvider导入/导出x509公钥blob和PKCS8私钥blob,c#,cryptography,rsa,public-key-encryption,C#,Cryptography,Rsa,Public Key Encryption,首先,让我声明我不是密码专家,但我知道基础知识 我希望能够: 从X509公钥blob获取RSACryptServiceProvider实例 从PKCS8私钥blob获取RSACryptServiceProvider实例 将公钥从RSACryptServiceProvider实例导出为x509公钥blob 将私钥从RSACryptServiceProvider实例导出为PKCS8 blob 首先,Java中的byte与.Net中的byte不同。Java只有带符号的整数,因此Javabyte的范围从

首先,让我声明我不是密码专家,但我知道基础知识

我希望能够:

  • 从X509公钥blob获取RSACryptServiceProvider实例
  • 从PKCS8私钥blob获取RSACryptServiceProvider实例
  • 将公钥从RSACryptServiceProvider实例导出为x509公钥blob
  • 将私钥从RSACryptServiceProvider实例导出为PKCS8 blob

  • 首先,Java中的
    byte
    与.Net中的
    byte
    不同。Java只有带符号的整数,因此Java
    byte
    的范围从-128到127,而.Net
    byte
    的范围从0到255。但我不确定这是否是问题所在,因为Base64字符串依赖于位模式。尝试在正数范围内使用较大的类型,并仅使用较低的8位


    第二,关于坏的提供者版本的消息可能表明上述原因,或者可能只是一个误导性的文本,这并没有真正的帮助。我记得我曾经遇到过同样的错误消息,很难找到真正的原因。几分钟前的快速搜索也没有成功。在我的情况下,我有一个完全不同的情况,所以我不能直接指出你的问题。相反,我建议您检查RSA算法的填充、加密模式、base64转换和相关内容,并尝试找到一种替代方法来实现您之前想要的效果。在前往那里的途中,您可能会遇到实际问题。

    首先,Java中的
    字节与.Net中的
    字节不同。Java只有带符号的整数,因此Java
    byte
    的范围从-128到127,而.Net
    byte
    的范围从0到255。但我不确定这是否是问题所在,因为Base64字符串依赖于位模式。尝试在正数范围内使用较大的类型,并仅使用较低的8位


    第二,关于坏的提供者版本的消息可能表明上述原因,或者可能只是一个误导性的文本,这并没有真正的帮助。我记得我曾经遇到过同样的错误消息,很难找到真正的原因。几分钟前的快速搜索也没有成功。在我的情况下,我有一个完全不同的情况,所以我不能直接指出你的问题。相反,我建议您检查RSA算法的填充、加密模式、base64转换和相关内容,并尝试找到一种替代方法来实现您之前想要的效果。在去那里的路上,你可能会偶然发现实际的问题。

    环顾了一整天之后,我发现了这个问题,我选择了实现目标1、2和3所需的代码

    由于Jrnker只提供从PKCS1 blob获取RSACryptoServiceProvider的方法(我需要的是从PKCS8 blob获取RSACryptoServiceProvider),我一直在寻找实现目标4的方法。然后我找到并选择了所需的代码,以实现目标4

    然后我开始编译一个包含所需方法和类的类

    这是我的演示课:

    using System;
    
    namespace RSAKeyTests
    {
        class Demo
        {
            static void Main(string[] args)
            {
                //EXPORTED KEYS
                string importedPublicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhbVC4aUR+XRCepBcPlod69wruXqwW9yL/YJYvuaQ33QxUoAehQ0z4SuphHwEPxQp/qLqucmE6XKlEeTksFAmaGM88uuGessqMZmdu9WFhc07MWLTCifR43IRtGEeWeFSWjUI6mNRrShP3QQ3+Z6e7w+HRA2RpmgNgEhJRvECHAKpcpHvP9o5Sq6q/dIAyR6NEjRFhfud27rFtnWrLj+ZmIsScemvks4vh8V3n8EzxxRE8nzVuZYr4v4NNH+q95XgIadHZ1Y6ICXJgX2NfacNRQl9+SEv0Wo8lbmFSIO3jHqyiWuSugv7R3/rQPRXHT6HJAtw0tBiPOBitMkTzqOvIwIDAQAB";
                string importedPrivateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFtULhpRH5dEJ6kFw+Wh3r3Cu5erBb3Iv9gli+5pDfdDFSgB6FDTPhK6mEfAQ/FCn+ouq5yYTpcqUR5OSwUCZoYzzy64Z6yyoxmZ271YWFzTsxYtMKJ9HjchG0YR5Z4VJaNQjqY1GtKE/dBDf5np7vD4dEDZGmaA2ASElG8QIcAqlyke8/2jlKrqr90gDJHo0SNEWF+53busW2dasuP5mYixJx6a+Szi+HxXefwTPHFETyfNW5livi/g00f6r3leAhp0dnVjogJcmBfY19pw1FCX35IS/RajyVuYVIg7eMerKJa5K6C/tHf+tA9FcdPockC3DS0GI84GK0yRPOo68jAgMBAAECggEAJ/Dalr8RnHvPM/+Vnoaa847kfNaaggZixwq96eDEHAwAg82D0Gj+O2AolkvZlOI4HTmbdn4tNvMpPiwq6EQ5BOvIFCSpGltAMmraBHcnGK4S5ZDIy/rTJuc3RLPSNjUpvYqkLCgZCOnG2ZXeBrIMdgskc/69qIDir5RoV0m9QJJYU7pfrfErWYr/eqb1t7eZtTBAg+LAjKUMUq68WoJiBSBRPbAvlyFoc6tyk0ftngsF4OPVbwZQyYC2vLmxVrr1/YQbEgjpuJwQ0bONL6G9PAH6O+h10ILk9nyJY2c9gOXU0tz+foJ47naM12wCJETEy9JGeAiN4NLz5wRKTZzZwQKBgQDCOEJGDgtmSM0bDv4vPuxbacFgGTgRAKTs6sG9E1Cf3LNBLDP9OhfRkXFc192PmQRAktaZAN89zXeGxK1tLbJ3003qKXw05K3KOksVjJ7AH4Yhurv3VWmFZB8pryUsxIp+rm/5GLf4LfptUmBO6R4+jTfJVRBtK4A9KmkbY7BjgwKBgQCwPWayTgd0fmDqJxptWfPThcUw3/cG6EWTpnx1dSOdaBHzewRwq/8/i4vs314/onLggXgZTIkPU7y8ylTmz5KcaPIQkmRSSSL0Y2yzMGcHnylj7ysgBLw23k/PVzGSsMZ6ly7lE03SNQ3tyg6u0lc3pbT8ZLHf/x913stxSSiT4QKBgQChdgnKmZRqhS1WSGGSP3pZCJNFY9HTeLijaQqFOFB3hg/Tp37VDv2MMKCQsbi0z13UnP4glrQAehbbCBixQiMzMIx+ldx3UIEWNN4E3TGAwPROiCIJnY0q4rBxg/SgwgftBvF5oU4X2YluZuQ/1ddZ4ya0jq4oQ9jJgL9+kKKsJwKBgQCndbBfPEVZK7xqwT0bKp3EHxd/mU/gAFQcN9WKxgNRTdHAyOMvLD8c4jvSl2u2i2UcbejwIQkaxzZPLPH/XrywYgegN3mbtmLAVLi0iwla9KEfk+ImSlmMyTCMkw1HlTECyySEBhOr6T2S9Kt+8d5twcZ3DDb34DLEjS5CNoGYAQKBgDCEyhrg2lwyYwrL26ohNNuzgiabC5IKCgHlMpsUQjoCid9awCSb2iROf7iZIBoDyzXqgEQWTAf2clpJxgHz0necVw2sXP8wGcJXJ+e/lXNfPaC4z2QRnQ6i2iV88jRlWLK+S403hGnK0L/SDu9LtBhHwy6r/qRGT14ourqS6x7O";
                byte[] importedPublicKeyBytes = Convert.FromBase64String(importedPublicKeyBase64);
                byte[] importedPrivateKeyBytes = Convert.FromBase64String(importedPrivateKeyBase64);
    
                //PRINT INFO
                Console.WriteLine("------   IMPORTED KEY PAIR:   ------\n");
                Console.WriteLine("PUBLIC KEY:\n"+importedPublicKeyBase64+"\n\n");
                Console.WriteLine("PRIVATE KEY:\n" + importedPrivateKeyBase64 + "\n\n");
    
                //GENERATING RSACRYPTOSERVICEPROVIDER FROM X509 PUBLIC KEY BLOB
                using (var providerFromX509pubKey = RSAKeyUtils.DecodePublicKey(importedPublicKeyBytes))
                {
                    providerFromX509pubKey.PersistKeyInCsp = false; //DO NOT STORE IN KEYSTORE
    
                    //EXPORT TO X509 PUBLIC KEY BLOB
                    byte[] x509pubKeyBytes = RSAKeyUtils.PublicKeyToX509(providerFromX509pubKey.ExportParameters(false));
    
                    //CONVERT TO BASE64
                    string x509pubKeyBase64 = Convert.ToBase64String(x509pubKeyBytes);
    
                    //PRINT INFO
                    Console.WriteLine("------   PUBLIC KEY TO EXPORT   ------");
                    Console.WriteLine("Public key to export matches imported? "+importedPublicKeyBase64.Equals(x509pubKeyBase64));
                    Console.WriteLine(x509pubKeyBase64+"\n\n");
                }
    
                //GENERATING RSACRYPTOSERVICEPROVIDER FROM PKCS8 PRIVATE KEY BLOB
                using (var providerFromPKCS8privKey = RSAKeyUtils.DecodePrivateKeyInfo(importedPrivateKeyBytes))
                {
                    providerFromPKCS8privKey.PersistKeyInCsp = false; //DO NOT STORE IN KEYSTORE
    
                    //EXPORT TO PKCS8 PRIVATE KEY BLOB
                    byte[] pkcs8privKeyBytes = RSAKeyUtils.PrivateKeyToPKCS8(providerFromPKCS1privKey.ExportParameters(true));
    
                    //CONVERT TO BASE64
                    string pkcs8privKeyBase64 = Convert.ToBase64String(pkcs8privKeyBytes);
    
                    //PRINT INFO
                    Console.WriteLine("------   PRIVATE KEY TO EXPORT   ------");
                    Console.WriteLine("Private key to export matches imported? " + importedPrivateKeyBase64.Equals(pkcs8privKeyBase64));
                    Console.WriteLine(pkcs8privKeyBase64);
                }
    
                    //PREVENTS THE PROGRAM FROM EXITING
                    Console.ReadKey();
            }
        }
    }
    


    我希望这能对其他人有用。

    在环顾了一整天之后,我发现了这一点,并选择了实现目标1、2和3所需的代码

    由于Jrnker只提供从PKCS1 blob获取RSACryptoServiceProvider的方法(我需要的是从PKCS8 blob获取RSACryptoServiceProvider),我一直在寻找实现目标4的方法。然后我找到并选择了所需的代码,以实现目标4

    然后我开始编译一个包含所需方法和类的类

    这是我的演示课:

    using System;
    
    namespace RSAKeyTests
    {
        class Demo
        {
            static void Main(string[] args)
            {
                //EXPORTED KEYS
                string importedPublicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhbVC4aUR+XRCepBcPlod69wruXqwW9yL/YJYvuaQ33QxUoAehQ0z4SuphHwEPxQp/qLqucmE6XKlEeTksFAmaGM88uuGessqMZmdu9WFhc07MWLTCifR43IRtGEeWeFSWjUI6mNRrShP3QQ3+Z6e7w+HRA2RpmgNgEhJRvECHAKpcpHvP9o5Sq6q/dIAyR6NEjRFhfud27rFtnWrLj+ZmIsScemvks4vh8V3n8EzxxRE8nzVuZYr4v4NNH+q95XgIadHZ1Y6ICXJgX2NfacNRQl9+SEv0Wo8lbmFSIO3jHqyiWuSugv7R3/rQPRXHT6HJAtw0tBiPOBitMkTzqOvIwIDAQAB";
                string importedPrivateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFtULhpRH5dEJ6kFw+Wh3r3Cu5erBb3Iv9gli+5pDfdDFSgB6FDTPhK6mEfAQ/FCn+ouq5yYTpcqUR5OSwUCZoYzzy64Z6yyoxmZ271YWFzTsxYtMKJ9HjchG0YR5Z4VJaNQjqY1GtKE/dBDf5np7vD4dEDZGmaA2ASElG8QIcAqlyke8/2jlKrqr90gDJHo0SNEWF+53busW2dasuP5mYixJx6a+Szi+HxXefwTPHFETyfNW5livi/g00f6r3leAhp0dnVjogJcmBfY19pw1FCX35IS/RajyVuYVIg7eMerKJa5K6C/tHf+tA9FcdPockC3DS0GI84GK0yRPOo68jAgMBAAECggEAJ/Dalr8RnHvPM/+Vnoaa847kfNaaggZixwq96eDEHAwAg82D0Gj+O2AolkvZlOI4HTmbdn4tNvMpPiwq6EQ5BOvIFCSpGltAMmraBHcnGK4S5ZDIy/rTJuc3RLPSNjUpvYqkLCgZCOnG2ZXeBrIMdgskc/69qIDir5RoV0m9QJJYU7pfrfErWYr/eqb1t7eZtTBAg+LAjKUMUq68WoJiBSBRPbAvlyFoc6tyk0ftngsF4OPVbwZQyYC2vLmxVrr1/YQbEgjpuJwQ0bONL6G9PAH6O+h10ILk9nyJY2c9gOXU0tz+foJ47naM12wCJETEy9JGeAiN4NLz5wRKTZzZwQKBgQDCOEJGDgtmSM0bDv4vPuxbacFgGTgRAKTs6sG9E1Cf3LNBLDP9OhfRkXFc192PmQRAktaZAN89zXeGxK1tLbJ3003qKXw05K3KOksVjJ7AH4Yhurv3VWmFZB8pryUsxIp+rm/5GLf4LfptUmBO6R4+jTfJVRBtK4A9KmkbY7BjgwKBgQCwPWayTgd0fmDqJxptWfPThcUw3/cG6EWTpnx1dSOdaBHzewRwq/8/i4vs314/onLggXgZTIkPU7y8ylTmz5KcaPIQkmRSSSL0Y2yzMGcHnylj7ysgBLw23k/PVzGSsMZ6ly7lE03SNQ3tyg6u0lc3pbT8ZLHf/x913stxSSiT4QKBgQChdgnKmZRqhS1WSGGSP3pZCJNFY9HTeLijaQqFOFB3hg/Tp37VDv2MMKCQsbi0z13UnP4glrQAehbbCBixQiMzMIx+ldx3UIEWNN4E3TGAwPROiCIJnY0q4rBxg/SgwgftBvF5oU4X2YluZuQ/1ddZ4ya0jq4oQ9jJgL9+kKKsJwKBgQCndbBfPEVZK7xqwT0bKp3EHxd/mU/gAFQcN9WKxgNRTdHAyOMvLD8c4jvSl2u2i2UcbejwIQkaxzZPLPH/XrywYgegN3mbtmLAVLi0iwla9KEfk+ImSlmMyTCMkw1HlTECyySEBhOr6T2S9Kt+8d5twcZ3DDb34DLEjS5CNoGYAQKBgDCEyhrg2lwyYwrL26ohNNuzgiabC5IKCgHlMpsUQjoCid9awCSb2iROf7iZIBoDyzXqgEQWTAf2clpJxgHz0necVw2sXP8wGcJXJ+e/lXNfPaC4z2QRnQ6i2iV88jRlWLK+S403hGnK0L/SDu9LtBhHwy6r/qRGT14ourqS6x7O";
                byte[] importedPublicKeyBytes = Convert.FromBase64String(importedPublicKeyBase64);
                byte[] importedPrivateKeyBytes = Convert.FromBase64String(importedPrivateKeyBase64);
    
                //PRINT INFO
                Console.WriteLine("------   IMPORTED KEY PAIR:   ------\n");
                Console.WriteLine("PUBLIC KEY:\n"+importedPublicKeyBase64+"\n\n");
                Console.WriteLine("PRIVATE KEY:\n" + importedPrivateKeyBase64 + "\n\n");
    
                //GENERATING RSACRYPTOSERVICEPROVIDER FROM X509 PUBLIC KEY BLOB
                using (var providerFromX509pubKey = RSAKeyUtils.DecodePublicKey(importedPublicKeyBytes))
                {
                    providerFromX509pubKey.PersistKeyInCsp = false; //DO NOT STORE IN KEYSTORE
    
                    //EXPORT TO X509 PUBLIC KEY BLOB
                    byte[] x509pubKeyBytes = RSAKeyUtils.PublicKeyToX509(providerFromX509pubKey.ExportParameters(false));
    
                    //CONVERT TO BASE64
                    string x509pubKeyBase64 = Convert.ToBase64String(x509pubKeyBytes);
    
                    //PRINT INFO
                    Console.WriteLine("------   PUBLIC KEY TO EXPORT   ------");
                    Console.WriteLine("Public key to export matches imported? "+importedPublicKeyBase64.Equals(x509pubKeyBase64));
                    Console.WriteLine(x509pubKeyBase64+"\n\n");
                }
    
                //GENERATING RSACRYPTOSERVICEPROVIDER FROM PKCS8 PRIVATE KEY BLOB
                using (var providerFromPKCS8privKey = RSAKeyUtils.DecodePrivateKeyInfo(importedPrivateKeyBytes))
                {
                    providerFromPKCS8privKey.PersistKeyInCsp = false; //DO NOT STORE IN KEYSTORE
    
                    //EXPORT TO PKCS8 PRIVATE KEY BLOB
                    byte[] pkcs8privKeyBytes = RSAKeyUtils.PrivateKeyToPKCS8(providerFromPKCS1privKey.ExportParameters(true));
    
                    //CONVERT TO BASE64
                    string pkcs8privKeyBase64 = Convert.ToBase64String(pkcs8privKeyBytes);
    
                    //PRINT INFO
                    Console.WriteLine("------   PRIVATE KEY TO EXPORT   ------");
                    Console.WriteLine("Private key to export matches imported? " + importedPrivateKeyBase64.Equals(pkcs8privKeyBase64));
                    Console.WriteLine(pkcs8privKeyBase64);
                }
    
                    //PREVENTS THE PROGRAM FROM EXITING
                    Console.ReadKey();
            }
        }
    }
    


    我希望这对其他人有用。

    填充、加密模式和base64翻译都很好,因为我很久以前就依赖它们,从来没有遇到过问题。问题肯定出在密钥表示中……填充、加密模式和base64转换都很好,因为我很久以前就依赖它们了,从来没有遇到过问题。问题肯定出在密钥表示中……您使用私钥加密,使用公钥解密。这称为数字签名,在Java和C#中有特定的方法。真的是你想做的吗?通常使用公钥进行加密,使用私钥进行解密。还要注意的是,导入RSA公钥并不是件小事。@pedrofb i已经在上面了。我必须将二进制asn.1 X509PKInfo解析为一个RSAParameters对象。当我完成后,我会提供一个代码解决方案。谢谢你让我进入正确的轨道@pedrofbYou正在用私钥加密,用公钥解密。这称为数字签名,在Java和C#中有特定的方法。真的是你想做的吗?通常使用公钥进行加密,使用私钥进行解密。还要注意的是,导入RSA公钥并不是件小事。@pedrofb i已经在上面了。我必须将二进制asn.1 X509PKInfo解析为一个RSAParameters对象。当我完成后,我会提供一个代码解决方案。谢谢你让我进入正确的轨道@pedrofbIt对你的RSAKeyUtils非常有帮助,非常感谢。这对你的RSAKeyUtils非常有帮助,非常感谢。