2012-01-12 616 views
13

有谁知道一个简单的教程或如何在c#中使用充气城堡签名数据的示例代码。在Java中有大量的教程和示例。我在c#中找不到一个示例。有谁知道如何做到这一点?C#使用BouncyCastle与RSA签名数据

+0

有没有你想要使用BouncyCastle的这方面的任何原因? .NET有它自己的RSA加密类。 – blowdart 2012-01-12 18:33:22

+0

我想这是一个公平的问题。我过去曾在Java中使用过BouncyCastle,并且知道它在不需要兼容性的情况下对后端进行通信。它可能的.Net版本也是如此,但它似乎更不灵活,并有更多的选择与填充等。 – 2012-01-12 22:14:10

+0

这是有道理的 - 尤其是如果你担心互操作:) – blowdart 2012-01-13 01:09:42

回答

28

好吧我找不到任何关于如何做到这一点的文档。但是我最终搞清楚了。 我在这里粘贴完整的代码,希望它可以帮助未来的人。

该类将使用sha1散列为提供的字符串计算RSA签名并对其进行验证。

using System; 
using System.IO; 
using System.Text; 
using Org.BouncyCastle.Asn1; 
using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Parameters; 
using Org.BouncyCastle.OpenSsl; 
using Org.BouncyCastle.Security; 
using Org.BouncyCastle.Utilities.Encoders; 

namespace API.Crypto 
{ 
    public class RsaSha1Signing 
    { 
     private RsaKeyParameters MakeKey(String modulusHexString, String exponentHexString, bool isPrivateKey) 
     { 
      var modulus = new Org.BouncyCastle.Math.BigInteger(modulusHexString, 16); 
      var exponent = new Org.BouncyCastle.Math.BigInteger(exponentHexString, 16); 

      return new RsaKeyParameters(isPrivateKey, modulus, exponent); 
     } 

     public String Sign(String data, String privateModulusHexString, String privateExponentHexString) 
     { 
      /* Make the key */ 
      RsaKeyParameters key = MakeKey(privateModulusHexString, privateExponentHexString, true); 

      /* Init alg */ 
      ISigner sig = SignerUtilities.GetSigner("SHA1withRSA"); 

      /* Populate key */ 
      sig.Init(true, key); 

      /* Get the bytes to be signed from the string */ 
      var bytes = Encoding.UTF8.GetBytes(data); 

      /* Calc the signature */ 
      sig.BlockUpdate(bytes, 0, bytes.Length); 
      byte[] signature = sig.GenerateSignature(); 

      /* Base 64 encode the sig so its 8-bit clean */ 
      var signedString = Convert.ToBase64String(signature); 

      return signedString; 
     } 

     public bool Verify(String data, String expectedSignature, String publicModulusHexString, String publicExponentHexString) 
     { 
      /* Make the key */ 
      RsaKeyParameters key = MakeKey(publicModulusHexString, publicExponentHexString, false); 

      /* Init alg */ 
      ISigner signer = SignerUtilities.GetSigner("SHA1withRSA"); 

      /* Populate key */ 
      signer.Init(false, key); 

      /* Get the signature into bytes */ 
      var expectedSig = Convert.FromBase64String(expectedSignature); 

      /* Get the bytes to be signed from the string */ 
      var msgBytes = Encoding.UTF8.GetBytes(data); 

      /* Calculate the signature and see if it matches */ 
      signer.BlockUpdate(msgBytes, 0, msgBytes.Length); 
      return signer.VerifySignature(expectedSig); 
     } 
    } 
} 
+0

它帮助我很大,非常感谢你 – Recurrsion 2012-11-30 19:35:23

+0

你能评论http://stackoverflow.com/questions/18344670/rsa-and-publickey-interop-with-dotnet – gpa 2013-08-20 22:04:06

+0

好吧,最后。有人发布了明确的指示。非常感谢! – 2014-03-19 10:55:55

0

您是否试过Signtool。该工具将在Microsoft框架文件夹下。

+2

Signtool用于签署可执行文件,它不适用于数据。 “ – blowdart 2012-01-12 18:32:33

0

.NET不公开加密算法以供选择。还有很多RSA教程。

For example

+0

”.NET不公开加密算法以供选择。“那是什么意思?此链接不是RSA签名,它的加密。 – 2012-01-12 05:49:50

+0

这意味着你不能指定将用于加密的算法。我没有说链接是用于签名的。这是为了与RSA合作。 SignData只是RSACryptoServiceProvider上的另一种方法。 – 2012-01-12 21:14:37

4

看看Bouncy Castle的网站。有来源和例子的档案。 http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-src-ext.zip

作为一个例子,有很多NUnit测试。 下面是使用RSA算法作为样本加密数据字节数组的方法代码,但在Bouncy Castle源代码和测试中可以找到更多样本。

public static byte[] Encrypt(byte[] data, AsymmetricKeyParameter key) 
    { 
     RsaEngine e = new RsaEngine(); 
     e.Init(true, key); 
     int blockSize = e.GetInputBlockSize(); 
     List<byte> output = new List<byte>(); 

     for (int chunkPosition = 0; chunkPosition < data.Length; chunkPosition += blockSize) 
     { 
      int chunkSize = Math.Min(blockSize, data.Length - (chunkPosition * blockSize)); 
      output.AddRange(e.ProcessBlock(data, chunkPosition, chunkSize)); 
     } 
     return output.ToArray(); 
    }