2012-01-12 15 views
13

¿Alguien sabe de un simple tutorial o código de ejemplo de cómo firmar datos en C# usando castillo hinchable? En Java hay toneladas de tutoriales y muestras. No puedo encontrar un solo ejemplo en C#. ¿Alguien sabe como hacer esto?C# Sign Data con RSA usando BouncyCastle

+0

¿Hay alguna razón por la que desee utilizar bouncycastle para esto? .NET tiene sus propias clases de encriptación RSA. – blowdart

+0

Supongo que es una buena pregunta. He utilizado BouncyCastle en Java en el pasado y sé que funcionó sin problemas de compatibilidad con el backend con el que necesito comunicarme. Es posible que la versión .Net también lo haga, pero parece mucho menos flexible y tiene muchas menos opciones con paddings, etc. –

+0

Eso tiene sentido, especialmente si le preocupa la interoperabilidad :) – blowdart

Respuesta

28

Bien No pude encontrar ninguna documentación sobre cómo hacer esto. Pero terminé descifrándolo. Estoy pegando el código completo aquí, así que espero que pueda ayudar a alguien en el futuro.

Esta clase calculará una firma RSA con un hash sha1 para la cadena provista y también la verificará.

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

Me ayudó significativamente, muchas gracias – Recurrsion

+0

¿Puede comentar en http://stackoverflow.com/questions/18344670/rsa-and-publickey-interop-with-dotnet – gpa

+0

Bueno, finalmente. Alguien publicó una instrucción clara. ¡Muchas gracias! –

0

¿Has probado Signtool. Esta herramienta estará en la carpeta de Microsoft Framework.

+2

Signtool es para firmar ejecutables, no es para datos. – blowdart

0

.NET no expone los algoritmos de encriptación para la selección. Y hay muchos tutoriales para RSA.

For example.

+0

".NET no expone los algoritmos de encriptación para la selección." Qué significa eso? Este enlace no es una firma de RSA, es un encriptado. –

+0

Significa que no puede especificar el algoritmo que se usará para el cifrado. No dije que el enlace es para firmar. Es para trabajar con RSA. SignData es solo otro método en RSACryptoServiceProvider. –

4

Mire el sitio web de Bouncy Castle. Hay un archivo con fuentes y ejemplos. http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-src-ext.zip

Como ejemplos hay una gran cantidad de pruebas de NUnit. A continuación se muestra un código de método para cifrar la matriz de bytes de datos utilizando el algoritmo RSA como muestra, pero en las fuentes y pruebas de Bouncy Castle puede encontrar más ejemplos.

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(); 
    } 
Cuestiones relacionadas