Esta división fue analizado por especialistas para que tengas la garantía de la veracidad de nuestro tutorial.
Solución:
Bouncy Castle no admite formatos XML en absoluto. A menos que su caso de uso lo requiera estrictamente, le resultará mucho más fácil usar codificaciones Base64, con certificados (X.509) y privado. keys (PKCS#8) almacenado en formato PEM. Estos son todos string formatos, por lo que debería poder usarse con JSON directamente.
Hay otros problemas en los ejemplos de código: la firma debe usar el privado key, las firmas no deben tratarse como cadenas ASCII, posiblemente sus mensajes sean en realidad UTF8. Esperaría que las rutinas internas de señal/verificación se vieran así:
public string SignData(string msg, ECPrivateKeyParameters privKey)
try
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
signer.Init(true, privKey);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
byte[] sigBytes = signer.GenerateSignature();
return Convert.ToBase64String(sigBytes);
catch (Exception exc)
Console.WriteLine("Signing Failed: " + exc.ToString());
return null;
public bool VerifySignature(ECPublicKeyParameters pubKey, string signature, string msg)
try
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
byte[] sigBytes = Convert.FromBase64String(signature);
ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
signer.Init(false, pubKey);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(sigBytes);
catch (Exception exc)
Console.WriteLine("Verification failed with the error: " + exc.ToString());
return false;
Otro problema es que creo que .NET no obtuvo compatibilidad con ECDSA hasta .NET 3.5; en cualquier caso, no hay una clase ECDsa en .NET 1.1 (que es el objetivo de BC para la próxima versión 1.8; nos “modernizaremos” después de eso ), por lo que DotNetUtilities no es compatible con ECDSA. Sin embargo, podemos exportar a PKCS#12 e importar a BC. Un programa de ejemplo:
public void Program()
Console.WriteLine("Attempting to load cert...");
System.Security.Cryptography.X509Certificates.X509Certificate2 thisCert = LoadCertificate();
Console.WriteLine(thisCert.IssuerName.Name);
Console.WriteLine("Signing the text - Mary had a nuclear bomb");
byte[] pkcs12Bytes = thisCert.Export(X509ContentType.Pkcs12, "dummy");
Pkcs12Store pkcs12 = new Pkcs12StoreBuilder().Build();
pkcs12.Load(new MemoryStream(pkcs12Bytes, false), "dummy".ToCharArray());
ECPrivateKeyParameters privKey = null;
foreach (string alias in pkcs12.Aliases)
if (pkcs12.IsKeyEntry(alias))
privKey = (ECPrivateKeyParameters)pkcs12.GetKey(alias).Key;
break;
string signature = SignData("Mary had a nuclear bomb", privKey);
Console.WriteLine("Signature: " + signature);
Console.WriteLine("Verifying Signature");
var bcCert = DotNetUtilities.FromX509Certificate(thisCert);
if (VerifySignature((ECPublicKeyParameters)bcCert.GetPublicKey(), signature, "Mary had a nuclear bomb."))
Console.WriteLine("Valid Signature!");
else
Console.WriteLine("Signature NOT valid!");
Realmente no he probado ninguno de los códigos anteriores, pero debería darle algo para continuar. Tenga en cuenta que BC tiene key y generadores de certificados también, por lo que puede elegir usar BC para todo (¡excepto XML!), y exportar/importar a/desde .NET solo cuando sea necesario.
Gracias a la respuesta de Petter, quería agregar un código para verificar la firma con el algoritmo RSA.
public bool VerifySignature(AsymmetricKeyParameter pubKey, string signature, string msg)
try
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
byte[] sigBytes = Convert.FromBase64String(signature);
ISigner signer = SignerUtilities.GetSigner("SHA-256withRSA");
signer.Init(false, pubKey);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(sigBytes);
catch (Exception exc)
Console.WriteLine("Verification failed with the error: " + exc.ToString());
return false;
Reseñas y puntuaciones del tutorial
Tienes la opción de añadir valor a nuestra información colaborando tu veteranía en las interpretaciones.