ejemplo - encriptar y desencriptar sha256 c#
Cifrado de clave pública con RSACryptoServiceProvider (2)
aquí hay un ejemplo para ti:
public static void rsaPlayground()
{
byte[] data = new byte[] { 1, 2, 3, 4, 5 };
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();//make a new csp with a new keypair
var pub_key = csp.ExportParameters(false); // export public key
var priv_key = csp.ExportParameters(true); // export private key
var encData = csp.Encrypt(data, false); // encrypt with PKCS#1_V1.5 Padding
var decBytes = MyRSAImpl.plainDecryptPriv(encData, priv_key); //decrypt with own BigInteger based implementation
var decData = decBytes.SkipWhile(x => x != 0).Skip(1).ToArray();//strip PKCS#1_V1.5 padding
}
public class MyRSAImpl
{
private static byte[] rsaOperation(byte[] data, BigInteger exp, BigInteger mod)
{
BigInteger bData = new BigInteger(
data //our data block
.Reverse() //BigInteger has another byte order
.Concat(new byte[] { 0 }) // append 0 so we are allways handling positive numbers
.ToArray() // constructor wants an array
);
return
BigInteger.ModPow(bData, exp, mod) // the RSA operation itself
.ToByteArray() //make bytes from BigInteger
.Reverse() // back to "normal" byte order
.ToArray(); // return as byte array
/*
*
* A few words on Padding:
*
* you will want to strip padding after decryption or apply before encryption
*
*/
}
public static byte[] plainEncryptPriv(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.privExponent, myKey.Modulus);
}
public static byte[] plainEncryptPub(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.pubExponent, myKey.Modulus);
}
public static byte[] plainDecryptPriv(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.privExponent, myKey.Modulus);
}
public static byte[] plainDecryptPub(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.pubExponent, myKey.Modulus);
}
}
public class MyRSAParams
{
public static MyRSAParams fromRSAParameters(RSAParameters key)
{
var ret = new MyRSAParams();
ret.Modulus = new BigInteger(key.Modulus.Reverse().Concat(new byte[] { 0 }).ToArray());
ret.privExponent = new BigInteger(key.D.Reverse().Concat(new byte[] { 0 }).ToArray());
ret.pubExponent = new BigInteger(key.Exponent.Reverse().Concat(new byte[] { 0 }).ToArray());
return ret;
}
public BigInteger Modulus;
public BigInteger privExponent;
public BigInteger pubExponent;
}
Hace tiempo que reviso un artículo de CodeProject que explica cómo cifrar y descifrar utilizando el proveedor de RSA:
Si bien la versión anterior de 2009 tenía errores, la nueva versión de 2012 (con compatibilidad con System.Numerics.BigInteger) parece más confiable. Sin embargo, lo que le falta a esta versión es una forma de encriptar con una clave pública y descifrar usando la clave privada .
Por lo tanto, lo intenté yo mismo, pero obtengo basura cuando descifro. No estoy familiarizado con el proveedor de RSA, así que estoy a oscuras aquí. Es difícil encontrar más información sobre cómo se supone que debe funcionar.
¿Alguien ve lo que está mal con esto? Lo siguiente es ENcryption con una clave PUBLIC:
// Add 4 byte padding to the data, and convert to BigInteger struct
BigInteger numData = GetBig( AddPadding( data ) );
RSAParameters rsaParams = rsa.ExportParameters( false );
//BigInteger D = GetBig( rsaParams.D ); //only for private key
BigInteger Exponent = GetBig( rsaParams.Exponent );
BigInteger Modulus = GetBig( rsaParams.Modulus );
BigInteger encData = BigInteger.ModPow( numData, Exponent, Modulus );
return encData.ToByteArray();
¿Uso la gran "D" del proveedor cuando hago esto? Probablemente no, ya que es la clave pública que no tiene la "D".
Luego, la contraparte (descifrado usando la clave PRIVADA):
BigInteger numEncData = new BigInteger( cipherData );
RSAParameters rsaParams = rsa.ExportParameters( true );
BigInteger D = GetBig( rsaParams.D );
//BigInteger Exponent = GetBig( rsaParams.Exponent );
BigInteger Modulus = GetBig( rsaParams.Modulus );
BigInteger decData = BigInteger.ModPow( numEncData, D, Modulus );
byte[] data = decData.ToByteArray();
byte[] result = new byte[ data.Length - 1 ];
Array.Copy( data, result, result.Length );
result = RemovePadding( result );
Array.Reverse( result );
return result;
¿Necesito la "D" o el exponente aquí?
Obviamente necesito la criptografía para trabajar en ambos sentidos público-público público-privado. ¡Cualquier ayuda es muy apreciada!
Toma este ejemplo de codificación / decodificación
byte[] toEncryptData = Encoding.ASCII.GetBytes("hello world");
//Generate keys
RSACryptoServiceProvider rsaGenKeys = new RSACryptoServiceProvider();
string privateXml = rsaGenKeys.ToXmlString(true);
string publicXml = rsaGenKeys.ToXmlString(false);
//Encode with public key
RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider();
rsaPublic.FromXmlString(publicXml);
byte[] encryptedRSA = rsaPublic.Encrypt(toEncryptData, false);
string EncryptedResult = Encoding.Default.GetString(encryptedRSA);
//Decode with private key
var rsaPrivate = new RSACryptoServiceProvider();
rsaPrivate.FromXmlString(privateXml);
byte[] decryptedRSA = rsaPrivate.Decrypt(encryptedRSA, false);
string originalResult = Encoding.Default.GetString(decryptedRSA);