如何在Bouncy castle c#中使用RSA打开密钥?

时间:2021-08-23 18:30:03

How do I unwrap a key using RSA private key in Bouncy castle? I receive the already wrapped key which was wrapped using the RSA public key. I have the RSA key pair. I just cannot find the api in the C# Bouncy Castle that I can use to unwrap it.

如何在Bouncy城​​堡中使用RSA私钥打开密钥?我收到使用RSA公钥包装的已经包装的密钥。我有RSA密钥对。我在C#Bouncy Castle找不到api,我可以用来打开它。

This code in the C# source code (https://github.com/bcgit/bc-csharp) is currently commented out. The commented out lines for the RSA is exactly what I need, but when I try to use them it seems that its been removed or never implemented

C#源代码(https://github.com/bcgit/bc-csharp)中的此代码目前已被注释掉。 RSA的注释行正是我所需要的,但当我尝试使用它时,它似乎被删除或从未实现

Key key = cipher.unwrap(wrappedKey, "RSA", IBufferedCipher.PRIVATE_KEY);

The line above is exactly what I need. Why has it been commented out? The full function in WrapTest.cs is given below:

上面这一行正是我所需要的。为什么它被注释掉了? WrapTest.cs中的完整功能如下:

public ITestResult Perform()
{
    try
        {
//              IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/PKCS5Padding");
            IWrapper cipher = WrapperUtilities.GetWrapper("DES/ECB/PKCS5Padding");

            IAsymmetricCipherKeyPairGenerator fact = GeneratorUtilities.GetKeyPairGenerator("RSA");
            fact.Init(
                new RsaKeyGenerationParameters(
                    BigInteger.ValueOf(0x10001),
                    new SecureRandom(),
                    512,
                    25));

            AsymmetricCipherKeyPair keyPair = fact.GenerateKeyPair();

            AsymmetricKeyParameter priKey = keyPair.Private;
            AsymmetricKeyParameter pubKey = keyPair.Public;

            byte[] priKeyBytes = PrivateKeyInfoFactory.CreatePrivateKeyInfo(priKey).GetDerEncoded();

            CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator("DES");

//              Key wrapKey = keyGen.generateKey();
            byte[] wrapKeyBytes = keyGen.GenerateKey();
            KeyParameter wrapKey = new DesParameters(wrapKeyBytes);

//              cipher.Init(IBufferedCipher.WRAP_MODE, wrapKey);
            cipher.Init(true, wrapKey);
//              byte[] wrappedKey = cipher.Wrap(priKey);
            byte[] wrappedKey = cipher.Wrap(priKeyBytes, 0, priKeyBytes.Length);

//              cipher.Init(IBufferedCipher.UNWRAP_MODE, wrapKey);
            cipher.Init(false, wrapKey);

//              Key key = cipher.unwrap(wrappedKey, "RSA", IBufferedCipher.PRIVATE_KEY);
            byte[] unwrapped = cipher.Unwrap(wrappedKey, 0, wrappedKey.Length);

            //if (!Arrays.AreEqual(priKey.getEncoded(), key.getEncoded()))
            if (!Arrays.AreEqual(priKeyBytes, unwrapped))
            {
                return new SimpleTestResult(false, "Unwrapped key does not match");
            }

            return new SimpleTestResult(true, Name + ": Okay");
        }
        catch (Exception e)
        {
            return new SimpleTestResult(false, Name + ": exception - " + e.ToString());
        }

}

}

1 个解决方案

#1


2  

I'm not entirely clear on what you need, but you can use RSA keys to wrap and unwrap AES keys in Bouncycastle. Here is a Java example that creates an RSA keypair, saves the private key to a file, and then saves an AES key that has been wrapped in the public key.

我并不完全清楚你需要什么,但你可以使用RSA密钥在Bouncycastle中包装和解包AES密钥。下面是一个Java示例,它创建RSA密钥对,将私钥保存到文件,然后保存已包装在公钥中的AES密钥。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;

public class Main {

    private static final SecureRandom rand = new SecureRandom();

    public static void main(String[] args) throws Exception {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024, rand);
        KeyPair kp = kpg.generateKeyPair();
        // Write out private key to file, PKCS8-encoded DER
        Files.write(Paths.get("privkey.der"), kp.getPrivate().getEncoded());
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        kg.init(256, rand);
        SecretKey aesKey = kg.generateKey();

        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
        c.init(Cipher.WRAP_MODE, kp.getPublic(), rand);
        byte[] wrappedKey = c.wrap(aesKey);

        // Write out wrapped key
        Files.write(Paths.get("wrappedkey"), wrappedKey);
    }
}

And here is a C# example that consumes the output from the Java example and unwraps the AES key.

这是一个C#示例,它使用Java示例的输出并解开AES密钥。

using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace RSADecryptWithBouncy
{
    class MainClass
    {

        private static KeyParameter Unwrap(byte [] key, AsymmetricKeyParameter privKeyParam) {
            var wrapper = WrapperUtilities.GetWrapper("RSA/NONE/PKCS1PADDING");
            wrapper.Init(false, privKeyParam);
            var aesKeyBytes = wrapper.Unwrap(key, 0, key.Length);
            return new KeyParameter(aesKeyBytes);
        }

        public static void Main(string[] args)
        {
            var privKeyBytes = File.ReadAllBytes("../../privkey.der");
            var seq = Asn1Sequence.GetInstance(privKeyBytes);
            var rsaKeyParams = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq));
            var wrappedKey = File.ReadAllBytes("../../wrappedKey");
            var aesKey2 = Unwrap(wrappedKey, rsaKeyParams);
        }
    }
}

You will have to adapt this to your needs.

您必须根据自己的需要进行调整。

#1


2  

I'm not entirely clear on what you need, but you can use RSA keys to wrap and unwrap AES keys in Bouncycastle. Here is a Java example that creates an RSA keypair, saves the private key to a file, and then saves an AES key that has been wrapped in the public key.

我并不完全清楚你需要什么,但你可以使用RSA密钥在Bouncycastle中包装和解包AES密钥。下面是一个Java示例,它创建RSA密钥对,将私钥保存到文件,然后保存已包装在公钥中的AES密钥。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;

public class Main {

    private static final SecureRandom rand = new SecureRandom();

    public static void main(String[] args) throws Exception {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024, rand);
        KeyPair kp = kpg.generateKeyPair();
        // Write out private key to file, PKCS8-encoded DER
        Files.write(Paths.get("privkey.der"), kp.getPrivate().getEncoded());
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        kg.init(256, rand);
        SecretKey aesKey = kg.generateKey();

        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
        c.init(Cipher.WRAP_MODE, kp.getPublic(), rand);
        byte[] wrappedKey = c.wrap(aesKey);

        // Write out wrapped key
        Files.write(Paths.get("wrappedkey"), wrappedKey);
    }
}

And here is a C# example that consumes the output from the Java example and unwraps the AES key.

这是一个C#示例,它使用Java示例的输出并解开AES密钥。

using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace RSADecryptWithBouncy
{
    class MainClass
    {

        private static KeyParameter Unwrap(byte [] key, AsymmetricKeyParameter privKeyParam) {
            var wrapper = WrapperUtilities.GetWrapper("RSA/NONE/PKCS1PADDING");
            wrapper.Init(false, privKeyParam);
            var aesKeyBytes = wrapper.Unwrap(key, 0, key.Length);
            return new KeyParameter(aesKeyBytes);
        }

        public static void Main(string[] args)
        {
            var privKeyBytes = File.ReadAllBytes("../../privkey.der");
            var seq = Asn1Sequence.GetInstance(privKeyBytes);
            var rsaKeyParams = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq));
            var wrappedKey = File.ReadAllBytes("../../wrappedKey");
            var aesKey2 = Unwrap(wrappedKey, rsaKeyParams);
        }
    }
}

You will have to adapt this to your needs.

您必须根据自己的需要进行调整。