En pocas palabras, este es mi problema:base 64 codificados de clave pública para verificar la firma RSA
private string publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGUzbydMZS+fnkGTsUkDKEyFOGwghR234d5GjPnMIC0RFtXtw2tdcNM8I9Qk+h6fnPHiA7r27iHBfdxTP3oegQJWpbY2RMwSmOs02eQqpKx4QtIjWqkKk2Gmck5cll9GCoI8AUAA5e0D02T0ZgINDmo5yGPhGAAmqYrm8YiupwQIDAQAB";
/* Some transformation required, using publicKeyString to initiate a new RSACryptoServiceProvider object
*/
//for now:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] selfComputedHash = new byte[]; //left out of the example
byte[] signature = new byte[];
bool result = rsa.VerifyHash(selfComputedHash, CryptoConfig.MapNameToOID("SHA1"), signature);
Como se puede ver, el problema está iniciando una nueva RSACryptoServiceProvider con la cadena de clave pública dada codificada en Base64. Pude hacer la creación de instancias usando un objeto RSAParameters, cargado con byte [] para Módulo y Exponente derivado de esta cadena de clave pública usando un comando de shell OpenSSL. Pero dado que esta clave pública puede cambiar en el futuro, quiero poder almacenarla en su forma original en una base de datos. Debe haber una manera más directa de lidiar con esto.
Muchos de los ejemplos que he leído hasta ahora evitan este problema exportando e importando las claves privadas y públicas generadas hacia y desde un objeto contenedor de clave y utilizándolo en el mismo código y por lo tanto no transfiriendo 'la clave en alguna cadena forma fuera de memoria. Algunas personas han expresado el mismo problema, tanto aquí en StackOverflow como en otros sitios, pero todavía no he podido encontrar una respuesta satisfactoria.
Cualquier idea es más que bienvenida.
Información de fondo: Mi compañero de comunicación calcula un SHA1-hash de 20 bytes a partir de una cadena de entrada de longitud variable, compuesta de la información contenida en varios campos de un mensaje codificado en ASCII. Este hash está firmado por RSA con la clave privada de mi compañero y enviado junto con el mensaje ASCII. Al llegar, calculo el hash SHA1 yo mismo, usando los mismos campos del mensaje ASCII y luego trato de verificar si estos campos no fueron alterados llamando a VerifyHash.
La clave se proporciona en 2 formas: regular y 'noNL'. La versión noNL se incluye en el código anterior, la versión normal es la siguiente:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGUzbydMZS+fnkGTsUkDKEyFO
GwghR234d5GjPnMIC0RFtXtw2tdcNM8I9Qk+h6fnPHiA7r27iHBfdxTP3oegQJWp
bY2RMwSmOs02eQqpKx4QtIjWqkKk2Gmck5cll9GCoI8AUAA5e0D02T0ZgINDmo5y
GPhGAAmqYrm8YiupwQIDAQAB
-----END PUBLIC KEY-----
Gracias, eso es bastante fácil. Buscaré en la biblioteca de BouncyCastle, pero ¿está seguro de que no hay forma de lograr esto usando solo la biblioteca Criptografía en .NET? – jscheppers
@jscheppers: Puedes hacerlo manualmente como poupou sugiere, pero no hay soporte directo para el formato en .NET. Una búsqueda rápida revela este ejemplo para decodificar manualmente: http://www.jensign.com/JavaScience/dotnet/pempublic/pempublic.cs, pero se ve un poco desordenado. –
Creo que prefiero tu solución BouncyCastle;) Ya lo he probado en mi implementación actual y funciona. ¡Marcaré tu publicación como la respuesta! – jscheppers