2017-08-06 103 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#。 –

相關問題