2017-08-06 79 views
-1

如何在Bouncy城​​堡中使用RSA私钥解开密钥?我收到已使用RSA公钥打包的已包装密钥。我有RSA密钥对。我无法在C#Bouncy Castle中找到可用于解开它的api。如何在Bouncy城​​堡c#中使用RSA打开密钥?

此代码在C#源代码(https://github.com/bcgit/bc-csharp)中目前已被注释掉。对于RSA注释掉线正是我所需要的,但是当我尝试使用它们似乎它已删除或没有实施

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

上面的线是正是我需要的。它为什么被评论了?在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()); 
     } 

}

+0

你在说Java,对吧?这段代码究竟在哪里注释掉了,你为什么依赖它?你可以在你的代码中使用它。 –

+0

您能否请包含更多代码?目前我们甚至不知道“cipher”变量的类型。 @ArtjomB。好吧,那里有'IBufferedCipher',感觉有点C#-ish。 –

+0

@MaartenBodewes我已经用更好的解释和更多的代码更新了这个问题。 – minime

回答

2

我不是你需要什么完全清楚,但可以使用RSA密钥在BouncyCastle的包​​,解开AES密钥。以下是创建RSA密钥对的Java示例,将私钥保存到文件中,然后保存已包装在公钥中的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); 
    } 
} 

这里是一个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); 
     } 
    } 
} 

您将不得不根据自己的需要进行调整。

+1

这个问题,据我了解,这需要在C#中缺少特殊包装模式。 –

+0

谢谢大家,我正在修复我的测试,以确保其他一切按预期工作,以便在我修复时能够正确验证。一旦测试完成,我会尝试@MaartenBodewes建议尝试加密和解开哪些对于AES应该没问题。 – minime

+0

@MaartenBodewes:第二个代码片段是C#。 –