RFC 2315. Used to sign and/or encrypt messages under a PKI. Used also for certificate dissemination (for instance as a response to a PKCS #10 message). Formed the basis for S/MIME, which is as of 2010 based on RFC 5652, an updated Cryptographic Message Syntax Standard (CMS). Often used for single sign-on.

Through many parts of the world, including the European Union and the United States, digital signing has been adopted as a way to implement electronic signatures that are considered legally binding. The PKCS7 package introduces digital signatures, digital certificates and the relationship between digital signatures and PKCS #7.

PKCS#7 is a complex format, also called CMS. Sun JCE has no direct support to PKCS#7. Bouncy Castle is used as cryptographic provider.

See also CAdES

1 Cryptographic Message Syntax (CMS)

The Cryptographic Message Syntax (CMS) is the IETF's standard for cryptographically protected messages. It can be used to digitally sign, digest, authenticate or encrypt any form of digital data.

CMS is based on the syntax of PKCS #7, which in turn is based on the Privacy-Enhanced Mail standard. The newest version of CMS (as of 2009) is specified in RFC 5652 (but see also RFC 5911 for updated ASN.1 modules conforming to ASN.1 2002).

The architecture of CMS is built around certificate-based key management, such as the profile defined by the PKIX working group.

CMS is used as the key cryptographic component of many other cryptographic standards, such as S/MIME, PKCS #12 and the RFC 3161 Digital timestamping protocol.

OpenSSL is open source software that can encrypt, decrypt, sign and verify, compress and uncompress CMS documents.

CMS enables interoperability between different products which can operate on the same document without knowing anything about other product (implementation and such other specific info related to the product). CMS achieves this by defining specific message formats for each data type (signed data, enveloped data, authenticated enveloped data). Hence, each product which support CMS format can exchange files or messages defined in the CMS format with no trouble.

2 Private Key and Certificate

We will use a Certificate to encrypt data and the PrivateKey to decrypt it. To run the examples we will extract the Certificate and the PrivateKey from a sample keystore.

The KeyStore example used is describe in the keystore (ks) package and it's located here

2.1 Export Certificate

We should provide our Certificate to all parts that will send us crypted messages. Those messages will be decypted only using our PrivateKey. We can export our Certificate Chain from our KeyStore by using the following code:

Copy
<script>
    var ks = new Ax.ks.KeyStoreManager("https://bitbucket.org/deister/axional-docs-resources/raw/master/KeyStores/swview/jks-files/jack.jks", "secret");
    console.log(ks.toResultSet());
    
    var pem = ks.exportKeyPairCertificate("jack", config => {
        config.setExportFormat("X509");
    	config.setPemEncode(true);
    	config.setExportChain(false);
    });
    console.log(new Ax.lang.String(pem));
</script>
+--------------+----+------+---------+---------+-------+-----------------------+------------------------+
|type          |lock|expiry|name     |algorithm|keysize|cerificate_expiry      |last_modified           |
+--------------+----+------+---------+---------+-------+-----------------------+------------------------+
|KeyPairEntry  |true|false |jack     |RSA      |   1024|2024-03-18 07:33:18 CET|2019-03-22 17:06:06 CET |
|TrustCertEntry|    |false |myservice|RSA      |   1024|2024-03-18 07:33:03 CET|2010-07-10 08:33:19 CEST|
|TrustCertEntry|    |false |swviewca |RSA      |   1024|2026-12-13 07:32:55 CET|2010-07-10 08:33:19 CEST|
+--------------+----+------+---------+---------+-------+-----------------------+------------------------+

00000000 2D 2D 2D 2D 2D 42 45 47 49 4E 20 43 45 52 54 49 -----BEGIN CERTI
00000010 46 49 43 41 54 45 2D 2D 2D 2D 2D 0A 4D 49 49 43 FICATE-----.MIIC
00000020 39 6A 43 43 41 6C 2B 67 41 77 49 42 41 67 49 4A 9jCCAl+gAwIBAgIJ
00000030 41 50 61 72 4F 6E 50 77 45 6B 4B 6C 4D 41 30 47 AParOnPwEkKlMA0G
00000040 43 53 71 47 53 49 62 33 44 51 45 42 42 51 55 41 CSqGSIb3DQEBBQUA
00000050 4D 49 47 4B 4D 51 73 77 43 51 59 44 0A 56 51 51 MIGKMQswCQYD.VQQ
00000060 47 45 77 4A 4D 53 7A 45 51 4D 41 34 47 41 31 55 GEwJMSzEQMA4GA1U
00000070 45 43 42 4D 48 56 32 56 7A 64 47 56 79 62 6A 45 ECBMHV2VzdGVybjE
00000080 51 4D 41 34 47 41 31 55 45 42 78 4D 48 51 32 39 QMA4GA1UEBxMHQ29
00000090 73 62 32 31 69 62 7A 45 57 4D 42 51 47 0A 41 31 sb21ibzEWMBQG.A1
936 byte(s) more
-----BEGIN CERTIFICATE-----
MIIC9jCCAl+gAwIBAgIJAParOnPwEkKlMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD
VQQGEwJMSzEQMA4GA1UECBMHV2VzdGVybjEQMA4GA1UEBxMHQ29sb21ibzEWMBQG
A1UEChMNU29mdHdhcmUgVmlldzERMA8GA1UECxMIVHJhaW5pbmcxLDAqBgNVBAMT
I1NvZnR3YXJlIFZpZXcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDcxMDA2
MzMxOFoXDTI0MDMxODA2MzMxOFowcjELMAkGA1UEBhMCTEsxEDAOBgNVBAgTB1dl
c3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xFjAUBgNVBAoTDVNvZnR3YXJlIFZpZXcx
ETAPBgNVBAsTCFRyYWluaW5nMRQwEgYDVQQDEwtKYWNrIERhbmllbDCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAqAIsXru2kWzNXidrgyapDb7GdmhUwNFx1rOi
mDyu2RrJN9sIv0Zi2B0Kp1xSQiBPWabXbtt3wB1LzS2P19tMC+MW7BTYz0mRg4n9
vSoa+mTJ3Ea6/v4W97a701BSEOlTxysVltqgO+D3gD9uNVpjiCNjXP3FlXrw44aD
nXwme3sCAwEAAaN7MHkwCQYDVR0TBAIwADAdBgNVHQ4EFgQUDp+pbeXQHmYiubDc
tF8b+C4g6V0wHwYDVR0jBBgwFoAU1rdiaEM7sE7BtSqZhTWT9Tqn9RQwLAYJYIZI
AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMA0GCSqGSIb3
DQEBBQUAA4GBACcLqPwC9cATSqe+Kes5r6kcgo8eN3QME+HVSQocFSaRVrZ8iOrl
0NAXway2JOGdjIFCn2gU4NAkrDAzjJ1AlwrfCT/1FDL5hu4BTdY13ZpwBf5MU6LB
6x2tc+Jbo4bQrskEEIfGpOcyuB/wBJtJQeONjLuY2ouX9pvaaHj2cpzS
-----END CERTIFICATE-----

You can take the Certificate export as PEM as source to setup PKCS7 encrypt.

3 Encrypt

Encrypt using the provided Certificate.

  • Encrypted source can be any convertible to InputStream data source.
  • Returned data is a byte[].

Copy
<script>
    var certificate = `
-----BEGIN CERTIFICATE-----
MIIC9jCCAl+gAwIBAgIJAParOnPwEkKlMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD
VQQGEwJMSzEQMA4GA1UECBMHV2VzdGVybjEQMA4GA1UEBxMHQ29sb21ibzEWMBQG
A1UEChMNU29mdHdhcmUgVmlldzERMA8GA1UECxMIVHJhaW5pbmcxLDAqBgNVBAMT
I1NvZnR3YXJlIFZpZXcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDcxMDA2
MzMxOFoXDTI0MDMxODA2MzMxOFowcjELMAkGA1UEBhMCTEsxEDAOBgNVBAgTB1dl
c3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xFjAUBgNVBAoTDVNvZnR3YXJlIFZpZXcx
ETAPBgNVBAsTCFRyYWluaW5nMRQwEgYDVQQDEwtKYWNrIERhbmllbDCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAqAIsXru2kWzNXidrgyapDb7GdmhUwNFx1rOi
mDyu2RrJN9sIv0Zi2B0Kp1xSQiBPWabXbtt3wB1LzS2P19tMC+MW7BTYz0mRg4n9
vSoa+mTJ3Ea6/v4W97a701BSEOlTxysVltqgO+D3gD9uNVpjiCNjXP3FlXrw44aD
nXwme3sCAwEAAaN7MHkwCQYDVR0TBAIwADAdBgNVHQ4EFgQUDp+pbeXQHmYiubDc
tF8b+C4g6V0wHwYDVR0jBBgwFoAU1rdiaEM7sE7BtSqZhTWT9Tqn9RQwLAYJYIZI
AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMA0GCSqGSIb3
DQEBBQUAA4GBACcLqPwC9cATSqe+Kes5r6kcgo8eN3QME+HVSQocFSaRVrZ8iOrl
0NAXway2JOGdjIFCn2gU4NAkrDAzjJ1AlwrfCT/1FDL5hu4BTdY13ZpwBf5MU6LB
6x2tc+Jbo4bQrskEEIfGpOcyuB/wBJtJQeONjLuY2ouX9pvaaHj2cpzS
-----END CERTIFICATE-----
`

    var message = "Secret message";
    var encryptedData = Ax.crypt.PKCS7.encrypt(certificate, message);
    console.log(encryptedData);
    new Ax.io.File("/tmp/test.encrypted").write(encryptedData);
</script>
00000000 30 80 06 09 2A 86 48 86 F7 0D 01 07 03 A0 80 30 0...*.H........0
00000010 80 02 01 00 31 82 01 34 30 82 01 30 02 01 00 30 ....1..40..0...0
00000020 81 98 30 81 8A 31 0B 30 09 06 03 55 04 06 13 02 ..0..1.0...U....
00000030 4C 4B 31 10 30 0E 06 03 55 04 08 13 07 57 65 73 LK1.0...U....Wes
00000040 74 65 72 6E 31 10 30 0E 06 03 55 04 07 13 07 43 tern1.0...U....C
00000050 6F 6C 6F 6D 62 6F 31 16 30 14 06 03 55 04 0A 13 olombo1.0...U...
00000060 0D 53 6F 66 74 77 61 72 65 20 56 69 65 77 31 11 .Software View1.
00000070 30 0F 06 03 55 04 0B 13 08 54 72 61 69 6E 69 6E 0...U....Trainin
00000080 67 31 2C 30 2A 06 03 55 04 03 13 23 53 6F 66 74 g1,0*..U...#Soft
00000090 77 61 72 65 20 56 69 65 77 20 43 65 72 74 69 66 ware View Certif
256 byte(s) more

3.1 Supported algorithms

By default, AES256_CBC will be used to encrypt. You can change the encryption method by selection one of the available enums.

Copy
<script>
	console.log(Ax.crypt.PKCS7.Algorithm);
</script>
[IDEA_CBC, CAMELLIA128_CBC, DES_EDE3_CBC, AES128_GCM, RC2_CBC, AES128_CCM, GOST28147_GCFB, CAMELLIA192_CBC, SEED_CBC, AES256_CBC, AES256_GCM, AES192_CCM, CAST5_CBC, AES128_CBC, DES_CBC, AES256_CCM, AES192_GCM, AES192_CBC, CAMELLIA256_CBC]

3.2 Selecting algorithm

To select an algorithm like CAMELLIA256_CBC use:

Copy
<script>
    var certificate = `
    -----BEGIN CERTIFICATE-----
    MIIC9jCCAl+gAwIBAgIJAParOnPwEkKlMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD
    VQQGEwJMSzEQMA4GA1UECBMHV2VzdGVybjEQMA4GA1UEBxMHQ29sb21ibzEWMBQG
    A1UEChMNU29mdHdhcmUgVmlldzERMA8GA1UECxMIVHJhaW5pbmcxLDAqBgNVBAMT
    I1NvZnR3YXJlIFZpZXcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDcxMDA2
    MzMxOFoXDTI0MDMxODA2MzMxOFowcjELMAkGA1UEBhMCTEsxEDAOBgNVBAgTB1dl
    c3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xFjAUBgNVBAoTDVNvZnR3YXJlIFZpZXcx
    ETAPBgNVBAsTCFRyYWluaW5nMRQwEgYDVQQDEwtKYWNrIERhbmllbDCBnzANBgkq
    hkiG9w0BAQEFAAOBjQAwgYkCgYEAqAIsXru2kWzNXidrgyapDb7GdmhUwNFx1rOi
    mDyu2RrJN9sIv0Zi2B0Kp1xSQiBPWabXbtt3wB1LzS2P19tMC+MW7BTYz0mRg4n9
    vSoa+mTJ3Ea6/v4W97a701BSEOlTxysVltqgO+D3gD9uNVpjiCNjXP3FlXrw44aD
    nXwme3sCAwEAAaN7MHkwCQYDVR0TBAIwADAdBgNVHQ4EFgQUDp+pbeXQHmYiubDc
    tF8b+C4g6V0wHwYDVR0jBBgwFoAU1rdiaEM7sE7BtSqZhTWT9Tqn9RQwLAYJYIZI
    AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMA0GCSqGSIb3
    DQEBBQUAA4GBACcLqPwC9cATSqe+Kes5r6kcgo8eN3QME+HVSQocFSaRVrZ8iOrl
    0NAXway2JOGdjIFCn2gU4NAkrDAzjJ1AlwrfCT/1FDL5hu4BTdY13ZpwBf5MU6LB
    6x2tc+Jbo4bQrskEEIfGpOcyuB/wBJtJQeONjLuY2ouX9pvaaHj2cpzS
    -----END CERTIFICATE-----
        `;

    var encryptedData = new Ax.crypt.PKCS7().encrypt(certificate, Ax.crypt.PKCS7.Algorithm.CAMELLIA256_CBC, message);

</script>

4 Decrypt

Using the KeyStore, obtain the PrivateKey for the certificate alias using. You need KeyStore password and alias password (in our example are 'secret' and 'moon'). Then, decrypt encrypted message using Private Key.

Copy
<script>
    
    var ks = new Ax.ks.KeyStoreManager("https://bitbucket.org/deister/axional-docs-resources/raw/master/KeyStores/swview/jks-files/jack.jks", "secret");
    var privateKey = ks.getPrivateKey("jack", "moon");
    var decryptedData = new Ax.crypt.PKCS7().decrypt(privateKey, new Ax.io.File("/tmp/test.encrypted"));
    console.log(decryptedData);
    
</script>
00000000 53 65 63 72 65 74 20 6D 65 73 73 61 67 65       Secret message

5 Sign

A digital signature is proof of the authenticity of digital messages, files, executables, and documents etc. in modern communication - by employing strong cryptographic techniques such as encryption and hashing. A unique digital ID (and a signing key) is required to create a digital signature. Digital IDs or certificates are based on asymmetric (or public key) cryptography which use key pairs (combination of public and private keys). Public keys are openly distributed among the communicating entities and the private (signing) keys are kept secret. The most common public key algorithm used is RSA.

A digital signature is basically a small block of data which is attached to the message to deliver the following security services:

  • Sender/Source Authentication: A message/file is digitally signed by the private key of the sender and sent to the other party. The other party can only verify the signature from the sender’s public key, hence the authentication of the sender is achieved.
  • Message Integrity: Since the sender created the digital signature and no-one else can alter or modify during transit it so it means that message integrity is maintained.
  • Non-Repudiation: Only the sender can create the digital signature which is verified by its public key, so the sender cannot deny the signature.

5.1 Relationship between PKCS7 Standard and Digital Signatures

PKCS #7 is one the most famous and extensively used standard from the series of PKCS (Public Key Cryptography Standards) by RSA Security LLC. PKCS #7 is the specific standard used for generation and verification of digital signatures and certificates managed by a PKI (Public Key Infrastructure). This standard served as the basis for the S/MIME (Secure/Multipurpose Internet Mail Extensions) standard. PKCS #7 proposes a broad-spectrum syntax and format for creation of digital signatures which is elaborated in detail in RFC 2315. It also allows compatibility with Privacy-Enhanced Mail (PEM) format which is the default and most commonly used file format for storage and sharing of crypto keys and digital certificates. PKCS #7 allows PEM compatible signed-data to be converted into PEM messages.

When using PKCS #7, the result is the exportation of one type “ContentInfo”, in addition to the various object identifiers that are produced. Within this method, there are six general content types:

  • Data
  • Signed Data
  • Enveloped Data
  • Signed-and-enveloped data
  • Digested data
  • Encrypted data

5.2 Sign an encrypted message

You can sign an encrypted message (or any other message). The signature can be verified later.

Copy
<script>
    var certificate = `
    -----BEGIN CERTIFICATE-----
    MIIC9jCCAl+gAwIBAgIJAParOnPwEkKlMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD
    VQQGEwJMSzEQMA4GA1UECBMHV2VzdGVybjEQMA4GA1UEBxMHQ29sb21ibzEWMBQG
    A1UEChMNU29mdHdhcmUgVmlldzERMA8GA1UECxMIVHJhaW5pbmcxLDAqBgNVBAMT
    I1NvZnR3YXJlIFZpZXcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDcxMDA2
    MzMxOFoXDTI0MDMxODA2MzMxOFowcjELMAkGA1UEBhMCTEsxEDAOBgNVBAgTB1dl
    c3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xFjAUBgNVBAoTDVNvZnR3YXJlIFZpZXcx
    ETAPBgNVBAsTCFRyYWluaW5nMRQwEgYDVQQDEwtKYWNrIERhbmllbDCBnzANBgkq
    hkiG9w0BAQEFAAOBjQAwgYkCgYEAqAIsXru2kWzNXidrgyapDb7GdmhUwNFx1rOi
    mDyu2RrJN9sIv0Zi2B0Kp1xSQiBPWabXbtt3wB1LzS2P19tMC+MW7BTYz0mRg4n9
    vSoa+mTJ3Ea6/v4W97a701BSEOlTxysVltqgO+D3gD9uNVpjiCNjXP3FlXrw44aD
    nXwme3sCAwEAAaN7MHkwCQYDVR0TBAIwADAdBgNVHQ4EFgQUDp+pbeXQHmYiubDc
    tF8b+C4g6V0wHwYDVR0jBBgwFoAU1rdiaEM7sE7BtSqZhTWT9Tqn9RQwLAYJYIZI
    AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMA0GCSqGSIb3
    DQEBBQUAA4GBACcLqPwC9cATSqe+Kes5r6kcgo8eN3QME+HVSQocFSaRVrZ8iOrl
    0NAXway2JOGdjIFCn2gU4NAkrDAzjJ1AlwrfCT/1FDL5hu4BTdY13ZpwBf5MU6LB
    6x2tc+Jbo4bQrskEEIfGpOcyuB/wBJtJQeONjLuY2ouX9pvaaHj2cpzS
    -----END CERTIFICATE-----
    `;

    var sign = new Ax.crypt.PKCS7().sign(certificate, privateKey, new Ax.io.File("/tmp/test.encrypted"));
    console.log(sign);

</script>
00000000 30 80 06 09 2A 86 48 86 F7 0D 01 07 02 A0 80 30 0...*.H........0
00000010 80 02 01 01 31 0F 30 0D 06 09 60 86 48 01 65 03 ....1.0...`.H.e.
00000020 04 02 01 05 00 30 80 06 09 2A 86 48 86 F7 0D 01 .....0...*.H....
00000030 07 01 A0 80 24 80 04 82 01 96 30 80 06 09 2A 86 ....$.....0...*.
00000040 48 86 F7 0D 01 07 03 A0 80 30 80 02 01 00 31 82 H........0....1.
00000050 01 34 30 82 01 30 02 01 00 30 81 98 30 81 8A 31 .40..0...0..0..1
00000060 0B 30 09 06 03 55 04 06 13 02 4C 4B 31 10 30 0E .0...U....LK1.0.
00000070 06 03 55 04 08 13 07 57 65 73 74 65 72 6E 31 10 ..U....Western1.
00000080 30 0E 06 03 55 04 07 13 07 43 6F 6C 6F 6D 62 6F 0...U....Colombo
00000090 31 16 30 14 06 03 55 04 0A 13 0D 53 6F 66 74 77 1.0...U....Softw

6 Verify

Finaly, you can verify signed data to ensure it's safe.

Copy
<script>
    var sign = new Ax.crypt.PKCS7().sign(certificate, privateKey, new Ax.io.File("/tmp/test.encrypted"));

    console.log(new Ax.crypt.PKCS7().verify(sign));
    
</script>
true

7 Extract data

TO DO

This section is incomplete and will be concluded as soon as possible.