Вы находитесь на странице: 1из 5

Cryptography with certificates

By Mathlab, 2 Nov 2012 0.00 (0 votes)

Introduction
How to do cryptography with X509 certificates.

Background
There is a great article on cryptography and I had to use certificates so I created a class around the functions from http://www.codeproject.com/Articles/10877/Public-Key-RSAEncryption-in-C-NET.

Using the code


Create a class project with C# and paste the code and build, after that you can add the reference to the project and you will be able to encrypt and decrypt using a X509 certificate.
Collapse | Copy Code

#region using using using using using using System; System.Collections; System.IO; System.Security.Cryptography; System.Security.Cryptography.X509Certificates; System.Text;

#endregion namespace CertificateCrypto { public class X509Cryptography { public readonly X509Certificate2 _CertFile; public readonly bool _FOaep; public X509Cryptography(X509Certificate2 certFile, bool fOAEP) { if (certFile != null) _CertFile = certFile; else throw new SystemException("Certificate is null"); _FOaep = fOAEP; } public X509Cryptography(X509Certificate2 certFile) { if (certFile != null) _CertFile = certFile; else throw new SystemException("Certificate is null"); _FOaep = false; } public static byte[] ReadStream(Stream input) {

using (var ms = new MemoryStream()) { input.CopyTo(ms); return ms.ToArray(); } } #region Encryption public string EncryptStringTest(string inputString) { // TODO: Add Proper Exception Handlers var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PublicKey.Key; int keySize = rsaCryptoServiceProvider.KeySize/8; byte[] bytes = Encoding.UTF32.GetBytes(inputString); // The hash function in use by the .NET RSACryptoServiceProvider here // is SHA1 // int maxLength = ( keySize ) - 2 // ( 2 * SHA1.Create().ComputeHash( rawBytes ).Length ); int maxLength = keySize - 42; int dataLength = bytes.Length; int iterations = dataLength/maxLength; var stringBuilder = new StringBuilder(); for (int i = 0; i <= iterations; i++) { var tempBytes = new byte[ (dataLength - maxLength*i > maxLength) ? maxLength : dataLength - maxLength*i]; Buffer.BlockCopy(bytes, maxLength*i, tempBytes, 0, tempBytes.Length); byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, _FOaep); // Be aware the RSACryptoServiceProvider reverses the order of // encrypted bytes. It does this after encryption and before // decryption. If you do not require compatibility with Microsoft // Cryptographic API (CAPI) and/or other vendors. Comment out the // next line and the corresponding one in the DecryptString function. Array.Reverse(encryptedBytes); // Why convert to base 64? // Because it is the largest power-of-two base printable using only // ASCII characters stringBuilder.Append(Convert.ToBase64String(encryptedBytes)); } return stringBuilder.ToString(); } public string DecryptStringTest(string inputString) { // TODO: Add Proper Exception Handlers var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PrivateKey; int keySize = rsaCryptoServiceProvider.KeySize/8;

int base64BlockSize = ((keySize/8)%3 != 0) ? (((keySize/8)/3)*4) + 4 : ((keySize/8)/3)*4; int iterations = inputString.Length/base64BlockSize; var arrayList = new ArrayList(); for (int i = 0; i < iterations; i++) { byte[] encryptedBytes = Convert.FromBase64String( inputString.Substring(base64BlockSize*i, base64BlockSize)); // Be aware the RSACryptoServiceProvider reverses the order of // encrypted bytes after encryption and before decryption. // If you do not require compatibility with Microsoft Cryptographic // API (CAPI) and/or other vendors. // Comment out the next line and the corresponding one in the // EncryptString function. Array.Reverse(encryptedBytes); arrayList.AddRange(rsaCryptoServiceProvider.Decrypt(encrypted Bytes, _FOaep)); } return Encoding.UTF32.GetString(arrayList.ToArray(Type.GetType("System.Byte")) as byte[]); } public string EncryptString(string inputString) { try { // TODO: Add Proper Exception Handlers var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PublicKey.Key; int keySize = rsaCryptoServiceProvider.KeySize/8; byte[] bytes = Encoding.UTF32.GetBytes(inputString); // The hash function in use by the .NET RSACryptoServiceProvider here // is SHA1 // int maxLength = ( keySize ) - 2 // ( 2 * SHA1.Create().ComputeHash( rawBytes ).Length ); int maxLength = keySize - 42; int dataLength = bytes.Length; int iterations = dataLength/maxLength; var stringBuilder = new StringBuilder(); for (int i = 0; i <= iterations; i++) { var tempBytes = new byte[ (dataLength - maxLength*i > maxLength) ? maxLength : dataLength - maxLength*i]; Buffer.BlockCopy(bytes, maxLength*i, tempBytes, 0, tempBytes.Length); byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, true); // Be aware the RSACryptoServiceProvider reverses the order of

// encrypted bytes. It does this after encryption and before // decryption. If you do not require compatibility with Microsoft // Cryptographic API (CAPI) and/or other vendors. Comment out the // next line and the corresponding one in the DecryptString function. Array.Reverse(encryptedBytes); // Why convert to base 64? // Because it is the largest power-of-two base printable using only // ASCII characters stringBuilder.Append(Convert.ToBase64String(encryptedByte s)); } return stringBuilder.ToString(); } catch (Exception ex) { throw new SystemException(ex.Message); } } public string DecryptString(string inputString) { try { // TODO: Add Proper Exception Handlers var rsaCryptoServiceProvider = (RSACryptoServiceProvider) _CertFile.PrivateKey; int dwKeySize = rsaCryptoServiceProvider.KeySize; int base64BlockSize = ((dwKeySize/8)%3 != 0) ? (((dwKeySize/8)/3)*4) + 4 : ((dwKeySize/8)/3)*4; int iterations = inputString.Length/base64BlockSize; var arrayList = new ArrayList(); for (int i = 0; i < iterations; i++) { byte[] encryptedBytes = Convert.FromBase64String( inputString.Substring(base64BlockSize*i, base64BlockSize)); // Be aware the RSACryptoServiceProvider reverses the order of // encrypted bytes after encryption and before decryption. // If you do not require compatibility with Microsoft Cryptographic // API (CAPI) and/or other vendors. // Comment out the next line and the corresponding one in the // EncryptString function. Array.Reverse(encryptedBytes); arrayList.AddRange(rsaCryptoServiceProvider.Decrypt( encryptedBytes, true)); } return Encoding.ASCII.GetString(arrayList.ToArray( Type.GetType("System.Byte")) as byte[]); } catch (Exception ex) { throw new SystemException(ex.Message);

} } #endregion } }

Вам также может понравиться