Rebex Security
XTS-AES and other handy security classes for .NET
Download 30-day free trial Buy from $99More .NET libraries
-
Rebex SFTP
.NET SFTP client
-
Rebex SSH Shell
.NET SSH Shell
-
Rebex Total Pack
All Rebex .NET libraries together
Back to feature list...
Cryptographic algorithms
On this page:
- Cryptographic Message Syntax (PKCS #7) SignedData
- Cryptographic Message Syntax (PKCS #7) SignedData with RSASSA-PSS
- Cryptographic Message Syntax (PKCS #7) EnvelopedData
- Cryptographic Message Syntax (PKCS #7) EnvelopedData with RSAES-OAEP
- Twofish symmetric cipher
- Blowfish symmetric cipher
- RC2 symmetric cipher
- ArcFour symmetric cipher (compatible with RC4)
- MD4 legacy hash algorithm
- MD5 legacy hash algorithm
- SHA-2 hash algorithms for .NET CF
- RSA public-key cryptography
- DSA public-key cryptography
- Diffie-Hellman key exchange algorithm
Cryptographic Message Syntax (PKCS #7) SignedData
Rebex.Security.Cryptography.Pkcs.SignedData
provides an API for creating and parsing CMS (PKCS #7) SignedData structures.
This is a standard format for electronic signature of binary data using X.509 certificates. CMS/PKCS #7's SignedData structure is part of many other standards such as S/MIME.
For example, this is how to create a detached .P7S signature file for a PDF document (or any other file) using a certificate:
// get a certificate with a private key var certificate = Certificate.LoadPfx("mycert.pfx", "password"); // load the content of a file we need to sign byte[] content = File.ReadAllBytes("document.pdf"); var contentInfo = new ContentInfo(content); // create a PKCS #7 SignedData object based on this, // the second argument specifies "detached" style var signedData = new SignedData(contentInfo, true); // add one ore more signers var signer = new SignerInfo(certificate); signedData.SignerInfos.Add(signer); // create the signature signedData.Sign(); // save the signature into a detached signature file using (var output = File.Create("document.pdf.p7s")) { signedData.Save(output); }
' get a certificate with a private key Dim cert = Certificate.LoadPfx("mycert.pfx", "password") ' load the content of a file we need to sign Dim content As Byte() = File.ReadAllBytes("document.pdf") Dim contentInfo = New ContentInfo(content) ' create a PKCS #7 SignedData object based on this, ' the second argument specifies "detached" style Dim signedData = New SignedData(contentInfo, True) ' add one ore more signers Dim signer = New SignerInfo(cert) signedData.SignerInfos.Add(signer) ' create the signature signedData.Sign() ' save the signature into a detached signature file Using output = File.Create("document.pdf.p7s") signedData.Save(output) End Using
At the other end, use this code to validate the detached .P7S signature:
// load the content of a file whose signature we wish to check byte[] content = File.ReadAllBytes("document.pdf"); var contentInfo = new ContentInfo(content); // create a PKCS #7 SignedData object base on this, // the second argument specifies "detached" style var signedData = new SignedData(contentInfo, true); // load the detached signature file using (Stream input = File.OpenRead("document.pdf.p7s")) { signedData.Load(input); } // validate the signature and the certificates SignatureValidationResult result = signedData.Validate(); // display the validation result if (result.Valid) { Console.WriteLine("Both signature and certificates are valid."); } else { Console.WriteLine("Signature or certificates are NOT valid."); Console.WriteLine("Signature problems: {0}", result.Status); Console.WriteLine("Certificate problems: {0}", result.CertificateValidationStatus); }
' load the content of a file whose signature we wish to check Dim content As Byte() = File.ReadAllBytes("document.pdf") Dim contentInfo = New ContentInfo(content) ' create a PKCS #7 SignedData object base on this, ' the second argument specifies "detached" style Dim signedData = New SignedData(contentInfo, True) ' load the detached signature file Using input As Stream = File.OpenRead("document.pdf.p7s") signedData.Load(input) End Using ' validate the signature and the certificates Dim result As SignatureValidationResult = signedData.Validate() ' display the validation result If result.Valid Then Console.WriteLine("Both signature and certificates are valid.") Else Console.WriteLine("Signature or certificates are NOT valid.") Console.WriteLine("Signature problems: {0}", result.Status) Console.WriteLine("Certificate problems: {0}", result.CertificateValidationStatus) End If
SignedData
object's encoding/decoding methods emit/parse an outer ContentInfo
structure, which is wrapped around the inner SignedData
structure.
This is a part of the CMS standard.
Cryptographic Message Syntax (PKCS #7) SignedData with RSASSA-PSS
In addition to classic RSA cryptographic signature scheme (PKCS#1 v1.5), Rebex.Security.Cryptography.Pkcs.SignedData
also supports
Probabilistic Signature Scheme (PSS),
whose security has been proven to directly relate to that of RSA itself. Because there is no such
proof for classic PKCS#1 scheme, RSA/PSS is quickly becoming the preferred signature scheme.
Rebex Security supports RSA with PSS on all platforms. Use the same code as above,
but specify the PaddingScheme
in SignerInfo
constructor call:
// ... // add one ore more signers var signer = new SignerInfo(certificate, new SignatureParameters() { PaddingScheme = SignaturePaddingScheme.Pss }); signedData.SignerInfos.Add(signer); // create the signature signedData.Sign(); // ...
Note: As of 2017, RSASSA-PSS is still not widely supported. OpenSSL supports it starting with version 1.0.2.
Cryptographic Message Syntax (PKCS #7) EnvelopedData
Rebex.Security.Cryptography.Pkcs.EnvelopedData
provides an API for creating and parsing CMS (PKCS #7) EnvelopedData structures.
This a standard format for encryption of binary data using X.509 certificates. CMS/PKCS #7's EnvelopedData structure is part of many other standards such as S/MIME.
For example, this is how to encrypt a PDF document (or any other file) using a certificate:
// get the recipient's certificate // (no private key needed) var certificate = Certificate.LoadDer("theircert.cer"); // load the content of a file we need to encrypt byte[] content = File.ReadAllBytes("document.pdf"); var contentInfo = new ContentInfo(content); // create a PKCS #7 EnvelopedData object based on this var envelopedData = new EnvelopedData(contentInfo); // add one ore more recipients var recipient = new KeyTransRecipientInfo(certificate); envelopedData.RecipientInfos.Add(recipient); // encrypt data envelopedData.Encrypt(); // save encrypted data into a .p7m file using (var output = File.Create("document.p7m")) { envelopedData.Save(output); }
' get the recipient's certificate ' (no private key needed) Dim cert = Certificate.LoadDer("theircert.cer") ' load the content of a file we need to encrypt Dim content As Byte() = File.ReadAllBytes("document.pdf") Dim contentInfo = New ContentInfo(content) ' create a PKCS #7 EnvelopedData object based on this Dim envelopedData = New EnvelopedData(contentInfo) ' add one ore more recipients Dim recipient = New KeyTransRecipientInfo(cert) envelopedData.RecipientInfos.Add(recipient) ' encrypt data envelopedData.Encrypt() ' save encrypted data into a .p7m file Using output = File.Create("document.p7m") envelopedData.Save(output) End Using
At the other end, use this code to decrypt the document:
// create an empty PKCS #7 EnvelopedData object var envelopedData = new EnvelopedData(); // load the encrypted file into it using (Stream input = File.OpenRead("document.p7m")) { envelopedData.Load(input); } // check whether it's possible to decrypt the file if (envelopedData.HasPrivateKey) { // decrypt it if possible (when a suitable decryption certificate with // an associated private key is available in Windows Certificate store) envelopedData.Decrypt(); // save decrypted content into a file File.WriteAllBytes("document.pdf", envelopedData.ContentInfo.ToArray()); } else { // otherwise, display a list of intended recipients foreach (RecipientInfo recipient in envelopedData.RecipientInfos) { SubjectIdentifier id = recipient.RecipientIdentifier; Console.WriteLine("Recipient info:"); if (id.Issuer != null) Console.WriteLine(" Certificate issuer: {0}", id.Issuer); if (id.SerialNumber != null) Console.WriteLine(" Serial number: {0}", BitConverter.ToString(id.SerialNumber)); if (id.SubjectKeyIdentifier != null) Console.WriteLine(" Subject key identifier: {0}", BitConverter.ToString(id.SubjectKeyIdentifier)); if (id.PublicKey != null) Console.WriteLine(" Public key: {0}", BitConverter.ToString(id.PublicKey)); if (id.PublicKeyAlgorithm != null) Console.WriteLine(" Key algorithm: {0}", id.PublicKeyAlgorithm.Oid); } }
' create an empty PKCS #7 EnvelopedData object Dim envelopedData = New EnvelopedData() ' load the encrypted file into it Using input As Stream = File.OpenRead("document.p7m") envelopedData.Load(input) End Using ' check whether it's possible to decrypt the file If envelopedData.HasPrivateKey Then ' decrypt it if possible (when a suitable decryption certificate with ' an associated private key is available in Windows Certificate store) envelopedData.Decrypt() ' save decrypted content into a file File.WriteAllBytes("document.pdf", envelopedData.ContentInfo.ToArray()) Else ' otherwise, display a list of intended recipients For Each recipient As RecipientInfo In envelopedData.RecipientInfos Dim id As SubjectIdentifier = recipient.RecipientIdentifier Console.WriteLine("Recipient info:") If id.Issuer IsNot Nothing Then Console.WriteLine(" Certificate issuer: {0}", id.Issuer) End If If id.SerialNumber IsNot Nothing Then Console.WriteLine(" Serial number: {0}", BitConverter.ToString(id.SerialNumber)) End If If id.SubjectKeyIdentifier IsNot Nothing Then Console.WriteLine(" Subject key identifier: {0}", BitConverter.ToString(id.SubjectKeyIdentifier)) End If If id.PublicKey IsNot Nothing Then Console.WriteLine(" Public key: {0}", BitConverter.ToString(id.PublicKey)) End If If id.PublicKeyAlgorithm IsNot Nothing Then Console.WriteLine(" Key algorithm: {0}", id.PublicKeyAlgorithm.Oid) End If Next End If
EnvelopedData
object's encoding/decoding methods emit/parse an outer ContentInfo
structure, which is wrapped around the inner EnvelopedData
structure.
This is a part of the CMS standard.
Cryptographic Message Syntax (PKCS #7) EnvelopedData with RSAES-OAEP
In addition to classic RSA cryptographic signature scheme (PKCS#1 v1.5), Rebex.Security.Cryptography.Pkcs.EnvelopedData
also supports
Optimal asymmetric encryption padding (OAEP),
which converts the traditional RSA deterministic encryption scheme into a probabilistic scheme.
RSA/OAEP offers protection against chosen ciphertext attacks and is quickly becoming the preferred padding scheme for RSA encryption.
Rebex Security supports RSA with OAEP on all platforms. Use the same code as above,
but specify the PaddingScheme
in KeyTransRecipientInfo
constructor call:
// ... // add one ore more recipients var recipient = new KeyTransRecipientInfo(certificate, new EncryptionParameters() { PaddingScheme = EncryptionPaddingScheme.Oaep }); envelopedData.RecipientInfos.Add(recipient); // encrypt data envelopedData.Encrypt(); // ...
Use EncryptionParameters.Label
to specify OAEP label (also known as input parameter).
Note: As of January 2018, RSAES-OAEP is still not widely supported. OpenSSL supports it starting with version 1.0.2.
Twofish symmetric cipher
Rebex.Security.Cryptography.TwofishManaged
is a managed implementation of Bruce Schneier's Twofish, a symmetric key block cipher.
It derives from .NET's SymmetricAlgorithm
object, which means it fits nicely into applications that already utilize another symmetric algorithms provided by .NET. For example,
it works nicely with .NET's CryptoStream
object.
Blowfish symmetric cipher
Rebex.Security.Cryptography.BlowfishManaged
is a managed implementation of Bruce Schneier's Twofish, a symmetric key block cipher.
It derives from .NET's SymmetricAlgorithm
object, which means it fits nicely into applications that already utilize another symmetric algorithms provided by .NET. For example,
it works nicely with .NET's CryptoStream
object.
RC2 symmetric cipher
Rebex.Security.Cryptography.ArcTwoManaged
is a managed implementation of RSA Security's RC2(r), a symmetric key block cipher.
It derives from .NET's SymmetricAlgorithm
object, which means it fits nicely into applications that already utilize another symmetric algorithms provided by .NET.
For example, it works nicely with .NET's CryptoStream
object.
Unlike .NET's RC2CryptoServiceProvider
object, ArcTwo
makes it possible to specify an effective key size with EffectiveKeySize
property.
ArcFour symmetric cipher (compatible with RC4)
Rebex.Security.Cryptography.ArcFourManaged
is a managed implementation of an algorithm compatible with RSA Security's RC4, a widely used symmetric key stream cipher.
It derives from .NET's SymmetricAlgorithm
object, which means it fits nicely into applications that already utilize another symmetric algorithms provided by .NET.
When using ArcFour
, please note that it's a stream cipher, unlike most other symmetric algorithms that are block ciphers.
MD4 legacy hash algorithm
Rebex.Security.Cryptography.MD4Managed
is a managed implementation of RSA Security's MD4 cryptographic hash function.
It derives from .NET's HashAlgorithm
object, which means it fits nicely into .NET applications.
The MD4 algorithm is no longer considered secure and should no longer be used. However, it is still useful to ensure interoperability with legacy systems that still use MD4 and can't be easily upgraded to use a more secure hash algorithm.
MD5 legacy hash algorithm
Rebex.Security.Cryptography.MD5Managed
is a managed implementation of RSA Security's MD5 cryptographic hash function.
It derives from .NET's HashAlgorithm
object, which means it fits nicely into .NET applications.
Unlike .NET's MD5CryptoServiceProvider
, it is fully managed and doesn't rely on Windows CryptoAPI.
The MD5 algorithm is no longer considered secure and should no longer be used. However, it is still useful to ensure interoperability with legacy systems that still use MD5 and can't be easily upgraded to use a more secure hash algorithm.
SHA-2 hash algorithms for .NET CF
Rebex.Security.Cryptography.SHA256Managed
, SHA384Managed
and SHA512Managed
are managed implementation of NSA's
SHA-2 cryptographic hash functions. These classes are only available on .NET Compact Framework, which lacks
the standard .NET System.Security.Cryptography.SHA256Managed
and System.Security.Cryptography.SHA256CryptoServiceProvider
classes
(and their SHA-384/SHA-512 counterparts). The three Rebex SHA-2 classes are fully managed and don't rely on Windows CryptoAPI. They are compatible
with the missing .NET classes.
RSA public-key cryptography
Rebex.Security.Cryptography.RSAManaged
is a managed implementation of RSA Security's RSA public key algorithm.
It derives from .NET's RSA
object, which means it fits nicely into .NET applications.
Unlike .NET's RSACryptoServiceProvider
, it is fully managed, doesn't rely on Windows CryptoAPI and implements EncryptValue
and DecryptValue
methods.
RSAManaged
does not currently support key generation.
DSA public-key cryptography
Rebex.Security.Cryptography.DSAManaged
is a managed implementation of DSA (Digital Signature Algorihm) public key algorithm.
It derives from .NET's DSA
object, which means it fits nicely into .NET applications.
Unlike .NET's DSACryptoServiceProvider
, it is fully managed and doesn't rely on Windows CryptoAPI.
DSAManaged
does not currently support key generation.
Diffie-Hellman key exchange algorithm
Rebex.Security.Cryptography.DiffieHellmanManaged
is a managed implementation of Diffie-Hellman key exchange algorithm.
Rebex.Security.Cryptography.DiffieHellmanCryptoServiceProvider
is another implementation that uses Windows CryptoAPI, making it faster.
Back to feature list...