He tenido el mismo problema con solo algunos certificados y de momento lo que realicé fue generar un nuevo CSD y asunto arreglado.
Este fin de semana tuve la necesidad de investigar a fondo ya que no era posible esperar a generar otro CSD y logré resolverlo; ya lo probé con varios casos y funciona correcto.
El problema es con este metodo:
Dim rsa As RSACryptoServiceProvider = opensslkey.DecodeEncryptedPrivateKeyInfo(llavePrivadaBytes, passwordSeguro)
Se produce un error, regresa nulo y por lo mismo no puede firmar la cadena original, la solucuón es dentro de un metodo que existe y el cual anexo. Por alguna causa los parámetros no tienen la longitud correcta y solo se rellena para cubrir el tamaño y con eso no marque error, utilizando la función ConvertRSAParametersField(byte[] bs, int size) que aparece al final
Código: Seleccionar todo
//------- Parses binary ans.1 RSA private key; returns RSACryptoServiceProvider ---
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
Console.WriteLine("showing components ..");
if (verbose)
{
showBytes("\nModulus", MODULUS);
showBytes("\nExponent", E);
showBytes("\nD", D);
showBytes("\nP", P);
showBytes("\nQ", Q);
showBytes("\nDP", DP);
showBytes("\nDQ", DQ);
showBytes("\nIQ", IQ);
}
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.P = P;
RSAparams.Q = Q;
//Valores Originales
//RSAparams.D = D;
//RSAparams.DP = DP;
//RSAparams.DQ = DQ;
//RSAparams.InverseQ = IQ;
//Ajuste realizado cuando algunos CSD marca error
RSAparams.D = ConvertRSAParametersField(D, MODULUS.Length);
RSAparams.DP = ConvertRSAParametersField(DP, P.Length);
RSAparams.DQ = ConvertRSAParametersField(DQ, Q.Length);
RSAparams.InverseQ = ConvertRSAParametersField(IQ, Q.Length);
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception e)
{
Console.WriteLine("Problem decrypting: {0}", e.Message);
return null;
}
finally { binr.Close(); }
}
private static byte[] ConvertRSAParametersField(byte[] bs, int size)
{
if (bs.Length == size)
return bs;
if (bs.Length > size)
throw new ArgumentException("Specified size too small", "size");
byte[] padded = new byte[size];
Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
return padded;
}
Espero les pueda servir ya que es un tema que lleva mucho tiempo, saludos a todos y suerte
Saludos...
Luis M