The first article is casual. NET using OpenSSL generated pem key file [do e-commerce friends may need] http://www.bkjia.com/kf/201202/121297.html algorithm only supports 1024-bit key file import. NET. Add the 2048-bit support today:
Using System;
Using System. Text;
Using System. Security. Cryptography;
Using System. Web;
Using System. IO;
Namespace Thinhunan. Cnblogs. Com. RSAUtility
{
/// <Summary>
/// Author http://thinhunan.cnblogs.com
/// </Summary>
Public class PemConverter
{
/// <Summary>
/// Convert the pem Public Key (1024 or 2048) to RSAParameters
/// </Summary>
/// <Param name = "pemFileConent"> pem public key content </param>
/// <Returns> RSAParamenters after conversion </returns>
Public static RSAParameters ConvertFromPemPublicKey (string pemFileConent)
{
If (string. IsNullOrEmpty (pemFileConent ))
{
Throw new ArgumentNullException ("pemFileConent", "This arg cann't be empty .");
}
PemFileConent = pemFileConent. replace ("----- begin public key -----",""). replace ("----- end public key -----",""). replace ("\ n ",""). replace ("\ r ","");
Byte [] keyData = Convert. FromBase64String (pemFileConent );
Bool keySize1024 = (keyData. Length = 162 );
Bool keySize2048 = (keyData. Length = 294 );
If (! (KeySize1024 | keySize2048 ))
{
Throw new ArgumentException ("pem file content is incorrect, Only support the key size is 1024 or 2048 ");
}
Byte [] pemModulus = (keySize1024? New byte [128]: new byte [256]);
Byte [] pemPublicExponent = new byte [3];
Array. Copy (keyData, (keySize1024? 29:33), pemModulus, 0, (keySize1024? ));
Array. Copy (keyData, (keySize1024? 159: 291), pemPublicExponent, 0, 3 );
RSAParameters para = new RSAParameters ();
Para. Modulus = pemModulus;
Para. Exponent = pemPublicExponent;
Return para;
}
/// <Summary>
/// Convert the pem private key (1024 or 2048) to RSAParameters
/// </Summary>
/// <Param name = "pemFileConent"> pem private key content </param>
/// <Returns> RSAParamenters after conversion </returns>
Public static RSAParameters ConvertFromPemPrivateKey (string pemFileConent)
{
If (string. IsNullOrEmpty (pemFileConent ))
{
Throw new ArgumentNullException ("pemFileConent", "This arg cann't be empty .");
}
PemFileConent = pemFileConent. replace ("----- begin rsa private key -----",""). replace ("----- end rsa private key -----",""). replace ("\ n ",""). replace ("\ r ","");
Byte [] keyData = Convert. FromBase64String (pemFileConent );
Bool keySize1024 = (keyData. Length = 609 | keyData. Length = 610 );
Bool keySize2048 = (keyData. Length = 1190 | keyData. Length = 1192 );
If (! (KeySize1024 | keySize2048 ))
{
Throw new ArgumentException ("pem file content is incorrect, Only support the key size is 1024 or 2048 ");
}
Int index = (keySize1024? 11: 12 );
Byte [] pemModulus = (keySize1024? New byte [128]: new byte [256]);
Array. Copy (keyData, index, pemModulus, 0, pemModulus. Length );
Index + = pemModulus. Length;
Index + = 2;
Byte [] pemPublicExponent = new byte [3];
Array. Copy (keyData, index, pemPublicExponent, 0, 3 );
Index + = 3;
Index + = 4;
If (int) keyData [index] = 0)
{
Index ++;
}
Byte [] pemPrivateExponent = (keySize1024? New byte [128]: new byte [256]);
Array. Copy (keyData, index, pemPrivateExponent, 0, pemPrivateExponent. Length );
Index + = pemPrivateExponent. Length;
Index + = (keySize1024? (Int) keyData [index + 1] = 64? 2: 3) :( (int) keyData [index + 2] = 128? 3: 4 ));
Byte [] pemPrime1 = (keySize1024? New byte [64]: new byte [128]);
Array. Copy (keyData, index, pemPrime1, 0, pemPrime1.Length );
Index + = pemPrime1.Length;
Index + = (keySize1024? (Int) keyData [index + 1] = 64? 2: 3): (int) keyData [index + 2] = 128? 3: 4 ));
Byte [] pemPrime2 = (keySize1024? New byte [64]: new byte [128]);
Array. Copy (keyData, index, pemPrime2, 0, pemPrime2.Length );
Index + = pemPrime2.Length;
Index + = (keySize1024? (Int) keyData [index + 1] = 64? 2: 3): (int) keyData [index + 2] = 128? 3: 4 ));
Byte [] pemExponent1 = (keySize1024? New byte [64]: new byte [128]);
Array. Copy (keyData, index, pemExponent1, 0, pemExponent1.Length );
Index + = pemExponent1.Length;
Index + = (keySize1024? (Int) keyData [index + 1] = 64? 2: 3): (int) keyData [index + 2] = 128? 3: 4 ));
Byte [] pemExponent2 = (keySize1024? New byte [64]: new byte [128]);
Array. Copy (keyData, index, pemExponent2, 0, pemExponent2.Length );
Index + = pemExponent2.Length;
Index + = (keySize1024? (Int) keyData [index + 1] = 64? 2: 3): (int) keyData [index + 2] = 128? 3: 4 ));
Byte [] pemCoefficient = (keySize1024? New byte [64]: new byte [128]);
Array. Copy (keyData, index, pemCoefficient, 0, pemCoefficient. Length );
RSAParameters para = new RSAParameters ();
Para. Modulus = pemModulus;
Para. Exponent = pemPublicExponent;
Para. D = pemPrivateExponent;
Para. P = pemPrime1;
Para. Q = pemPrime2;
Para. DP = pemExponent1;
Para. DQ = pemExponent2;
Para. InverseQ = pemCoefficient;
Return para;
}
}
}
Test encryption and decryption. The signature verification function is successful:
Static void Main (string [] args)
{
String privateKey = GetPemContent (@ "C: \ ftzl \ privatekey2048.pem ");
String publicKey = GetPemContent (@ "c: \ ftzl \ publickey2048.pem ");
// DebugRsaKey (privateKey, true );
TestSignAndEncrypt (privateKey, publicKey );
// TestVerifyOATransferSign ();
}
Static string GetPemContent (string filePath)
{
String content = File. ReadAllText (filePath, Encoding. ASCII );
Return content;
}
Public static void TestSignAndEncrypt (string privateKey, string publicKey)
{
// Sign
RSAParameters para = PemConverter. ConvertFromPemPrivateKey (privateKey );
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider ();
Rsa. ImportParameters (para );
Byte [] testData = Encoding. UTF8.GetBytes ("hello ");
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider ();
Byte [] signData = rsa. SignData (testData, md5 );
// Verify
RSAParameters paraPub = PemConverter. ConvertFromPemPublicKey (publicKey );
RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider ();
RsaPub. ImportParameters (paraPub );
If (rsaPub. VerifyData (testData, md5, signData ))
{
Console. WriteLine ("verify sign successful ");
}
Else
{
Console. WriteLine ("verify sign failed ");
}
// Encrypt and decrypt data
Byte [] encryptedData = rsaPub. Encrypt (testData, false );
Byte [] decryptedData = rsa. Decrypt (encryptedData, false );
Console. WriteLine (Encoding. UTF8.GetString (decryptedData ));
}
Author THINK (TAN zhenlin)