diff --git a/examples/How To Encrypt CMS via certificate/CMSEnvelopedExample.html b/examples/How To Encrypt CMS via certificate/CMSEnvelopedExample.html new file mode 100644 index 000000000..aa6a36c9a --- /dev/null +++ b/examples/How To Encrypt CMS via certificate/CMSEnvelopedExample.html @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2014, GMO GlobalSign + * Copyright (c) 2015, Peculiar Ventures + * All rights reserved. + * + * Author 2014-2015, Yury Strozhevsky . + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + + + + + + CMS Enveloped Example + + + + + + + + + + + + + + + + +
+

Put existing data or create new X.509 certificate and private key

+
+

+ + +

+

+ + +

+

+ Create +

+ + + + +
+
+
+

Work with CMS Enveloped data

+
+ + +

+ + +

+

+ + +

+

+ Encrypt +

+ + +

+ Decrypt +

+ + +
+
+ + \ No newline at end of file diff --git a/examples/How To Encrypt CMS via certificate/README.MD b/examples/How To Encrypt CMS via certificate/README.MD new file mode 100644 index 000000000..51af9f1ae --- /dev/null +++ b/examples/How To Encrypt CMS via certificate/README.MD @@ -0,0 +1,60 @@ +# Working with CMS EnvelopedData + +Working with with CMS Enveloped Data in PKIjs is done with the **org.pkijs.simpl.CMS_ENVELOPED_DATA** object. Utilizing this object you can encode/encrypt a new CMS Enveloped Data message, decode/decrypt an existing one or add recipients to it. Additionally to make it easier for web developers to work with these messages it is also possible to translate the message to JSON. + +## Encrypting +To create an encrypted message with PKIjs the first thing you must do is choose who you want to encrypt the message to. [PKIjs][] supports encrypting to recipients using the public keys in X.509 certificates as well as using preshared keys (KEK) or passwords. + +To add a recipient to a message you use one of these methods: +* addRecipientByCertificate; +* addRecipientByPreDefinedData; + +**addRecipientByCertificate** is used when encrypting a message to a the subject of an X.509 certificate; S/MIME encryption uses this approach. + +>**NOTE**: CMS EnvelopedData supports a concept of recipient types when encrypting to a subject of an certificate. At this time you **can not** specify the "type" of recipient. Certificates with RSA signatures the recipient's type will be **KeyTransRecipientInfo** and certificates with ECC signatures it will be type **KeyAgreeRecipientInfo**. It is not possible to support this case with WebCrypto at this time because there are no good support for the **DH** algorithm in all browsers ([FireFox has problems with exporting/importing keys][] and [Google Chrome has no implementation for **DH** at all][]). When this changes it will be possible to add support for **KeyAgreeRecipientInfo** for both RSA and ECC certificates. + +Parameters for **addRecipientByCertificate**: +* **certificate** - *org.pkijs.simpl.CERT* - The recipients certificate (a PKIjs parsed object); +* **parameters** - *Object* - The options to be used when encrypting the message; options include: + * **oaepHashAlgorithm** - *String* - The hash algorithm to be used with with RSASSA-OAEP. The default value is - SHA-512; + * **kdfAlgorithm** - *String* - The hash algorithm to be used when deriving keys for use with ECDH (when using ECC-based certificates). The default value is - SHA-512; + * **kekEncryptionLength** - *Number* - The length of the key to be use with AES-KW. The default value is - 256; +* **variant** - *Number* - A reserved value. The intention is to use this in the future to support specifying *“recipient type”*; for example *"variant = 1"* for *KeyTransRecipientInfo* type and *"variant = 2"* for **KeyAgreeRecipientInfo** type; + +**addRecipientByPreDefinedData** is used when encrypting to pre-defined keys (**KEKRecipientInfo**) and passwords (**PasswordRecipientInfo**). + +Parameters for **addRecipientByPreDefinedData**: +* **preDefinedData**. Type - **ArrayBuffer**. The key or password to be used to encrypt the message. +>**NOTE**: At this time (April 2015) Google Chrome supports only AES-KW-128 and AES-KW-256 algorithms. Thus to use the **KEKRecipientInfo** type you must provide 16 or 32 bytes in this field to use that option; +* **parameters** - *Object* - The options to be used when encrypting the message; options include: + * **keyIdentifier** - *ArrayBuffer* - Used for **KEKRecipientInfo**. Default value - A random initialized ArrayBuffer 16 bytes length; + * **hmacHashAlgorithm** - *String* - The hash algorithm to be used in PBKDF2 when producing the HMAC. Default value - SHA-512; + * **iterationCount** - *Number* - The iteration count used in PBKDF2. The default value is - 2048; + * **keyEncryptionAlgorithm** - *WebCrypto algorithm* - The key encryption algorithm to be used when encrypting the message. The default value is - { name: *"AES-KW"*, length: *256* }; + * **keyEncryptionAlgorithmParams** - *ASN1js parsed object* - Additional parameters used during key encryption. For example, for AES-CBC here we would put an "initialization vector". Default value - **new org.pkijs.asn1.NULL()**; +* **variant** - *Number* - Possible values: *variant = 1* is for **KEKRecipientInfo** and *variant = 2* is for **PasswordRecipientInfo**; + +Once all recipients have been added the message you call the **encrypt** method on **org.pkijs.simpl.CMS_ENVELOPED_DATA** object. + +The **encrypt** method has following parameters: +* **contentEncryptionAlgorithm** - *WebCrypto algorithm* - There is no default value for this parameter - At this time [PKIjs][] supports both AES-CBC and AES-GCM. +> **NOTE:** It is also technically possible to use AES-CTR, but seems that AES-CTR does not have an OID enabling it to be used in an interoperable with CMS Enveloped data messages; +* **contentToEncrypt** - *ArrayBuffer* - The data to encrypt; + +## Decrypting +To decrypt a message with PKIjs you use the **decrypt** method of **org.pkijs.simpl.CMS_ENVELOPED_DATA** object. + +The **decrypt** method has following parameters: +* **recipientIndex** - *Number* - The index (starting from 0) of the recipient that you want to decrypt the session key for. +> **NOTE:** In **KeyAgreeRecipientInfo** there is possibility to use one ephemeral ECDH key for many different recipients, inside one CMS Enveloped message. This case is not supported by [PKIjs][] - for each new recipient we use new ECDH ephemeral key. That is why [PKIjs][] has no "recipient's sub-indexes"; +* **parameters** - *Object* - The options to be used when decrypting the message; options include: + * **recipientCertificate** - *org.pkijs.simpl.CERT* - This field is mandatory for recipient's type **KeyAgreeRecipientInfo**; + * **recipientPrivateKey** - *ArrayBuffer* - The encoded PKCS#8 structure for recipient's private key. This field is mandatory for recipient's types **KeyTransRecipientInfo** and **KeyAgreeRecipientInfo**; + * **preDefinedData** - *ArrayBuffer* - Early used pre-shared data (pre-shared *"key encryption key"* or password). + +> **NOTE:** [PKIjs][] supports combinations of options not yet (as of April 2015) supported by OpenSSL and Microsoft CryptoAPI (and CNG). For example OpenSSL does not support PBKDF2 with AES-KW algorithms. And Microsoft CryptoAPI does not support **dhSinglePass-stdDH-sha1kdf-scheme** and **dhSinglePass-stdDH-sha512kdf-scheme** or any forms of CMS using pre-shared data. + + +[PKIjs]: http://pkijs.org/ +[FireFox has problems with exporting/importing keys]: https://docs.google.com/spreadsheet/ccc?key=0AiAcidBZRLxndE9LWEs2R1oxZ0xidUVoU3FQbFFobkE#gid=1 +[Google Chrome has no implementation for **DH** at all]: https://sites.google.com/a/chromium.org/dev/blink/webcrypto \ No newline at end of file diff --git a/examples/How To Encrypt CMS via password/CMSEnvelopedPreDefineDataExample.html b/examples/How To Encrypt CMS via password/CMSEnvelopedPreDefineDataExample.html new file mode 100644 index 000000000..293184057 --- /dev/null +++ b/examples/How To Encrypt CMS via password/CMSEnvelopedPreDefineDataExample.html @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2014, GMO GlobalSign + * Copyright (c) 2015, Peculiar Ventures + * All rights reserved. + * + * Author 2014-2015, Yury Strozhevsky . + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + + + + + + CMS Enveloped With Pre-Defined Data Example + + + + + + + + + + + + + + + + +
+

Work with CMS Enveloped data

+
+ + + + +

+ + +

+

+ + +

+

+ + +

+

+ Encrypt +

+ + +

+ Decrypt +

+ + +
+
+ + \ No newline at end of file diff --git a/examples/How To Encrypt CMS via password/README.MD b/examples/How To Encrypt CMS via password/README.MD new file mode 100644 index 000000000..51af9f1ae --- /dev/null +++ b/examples/How To Encrypt CMS via password/README.MD @@ -0,0 +1,60 @@ +# Working with CMS EnvelopedData + +Working with with CMS Enveloped Data in PKIjs is done with the **org.pkijs.simpl.CMS_ENVELOPED_DATA** object. Utilizing this object you can encode/encrypt a new CMS Enveloped Data message, decode/decrypt an existing one or add recipients to it. Additionally to make it easier for web developers to work with these messages it is also possible to translate the message to JSON. + +## Encrypting +To create an encrypted message with PKIjs the first thing you must do is choose who you want to encrypt the message to. [PKIjs][] supports encrypting to recipients using the public keys in X.509 certificates as well as using preshared keys (KEK) or passwords. + +To add a recipient to a message you use one of these methods: +* addRecipientByCertificate; +* addRecipientByPreDefinedData; + +**addRecipientByCertificate** is used when encrypting a message to a the subject of an X.509 certificate; S/MIME encryption uses this approach. + +>**NOTE**: CMS EnvelopedData supports a concept of recipient types when encrypting to a subject of an certificate. At this time you **can not** specify the "type" of recipient. Certificates with RSA signatures the recipient's type will be **KeyTransRecipientInfo** and certificates with ECC signatures it will be type **KeyAgreeRecipientInfo**. It is not possible to support this case with WebCrypto at this time because there are no good support for the **DH** algorithm in all browsers ([FireFox has problems with exporting/importing keys][] and [Google Chrome has no implementation for **DH** at all][]). When this changes it will be possible to add support for **KeyAgreeRecipientInfo** for both RSA and ECC certificates. + +Parameters for **addRecipientByCertificate**: +* **certificate** - *org.pkijs.simpl.CERT* - The recipients certificate (a PKIjs parsed object); +* **parameters** - *Object* - The options to be used when encrypting the message; options include: + * **oaepHashAlgorithm** - *String* - The hash algorithm to be used with with RSASSA-OAEP. The default value is - SHA-512; + * **kdfAlgorithm** - *String* - The hash algorithm to be used when deriving keys for use with ECDH (when using ECC-based certificates). The default value is - SHA-512; + * **kekEncryptionLength** - *Number* - The length of the key to be use with AES-KW. The default value is - 256; +* **variant** - *Number* - A reserved value. The intention is to use this in the future to support specifying *“recipient type”*; for example *"variant = 1"* for *KeyTransRecipientInfo* type and *"variant = 2"* for **KeyAgreeRecipientInfo** type; + +**addRecipientByPreDefinedData** is used when encrypting to pre-defined keys (**KEKRecipientInfo**) and passwords (**PasswordRecipientInfo**). + +Parameters for **addRecipientByPreDefinedData**: +* **preDefinedData**. Type - **ArrayBuffer**. The key or password to be used to encrypt the message. +>**NOTE**: At this time (April 2015) Google Chrome supports only AES-KW-128 and AES-KW-256 algorithms. Thus to use the **KEKRecipientInfo** type you must provide 16 or 32 bytes in this field to use that option; +* **parameters** - *Object* - The options to be used when encrypting the message; options include: + * **keyIdentifier** - *ArrayBuffer* - Used for **KEKRecipientInfo**. Default value - A random initialized ArrayBuffer 16 bytes length; + * **hmacHashAlgorithm** - *String* - The hash algorithm to be used in PBKDF2 when producing the HMAC. Default value - SHA-512; + * **iterationCount** - *Number* - The iteration count used in PBKDF2. The default value is - 2048; + * **keyEncryptionAlgorithm** - *WebCrypto algorithm* - The key encryption algorithm to be used when encrypting the message. The default value is - { name: *"AES-KW"*, length: *256* }; + * **keyEncryptionAlgorithmParams** - *ASN1js parsed object* - Additional parameters used during key encryption. For example, for AES-CBC here we would put an "initialization vector". Default value - **new org.pkijs.asn1.NULL()**; +* **variant** - *Number* - Possible values: *variant = 1* is for **KEKRecipientInfo** and *variant = 2* is for **PasswordRecipientInfo**; + +Once all recipients have been added the message you call the **encrypt** method on **org.pkijs.simpl.CMS_ENVELOPED_DATA** object. + +The **encrypt** method has following parameters: +* **contentEncryptionAlgorithm** - *WebCrypto algorithm* - There is no default value for this parameter - At this time [PKIjs][] supports both AES-CBC and AES-GCM. +> **NOTE:** It is also technically possible to use AES-CTR, but seems that AES-CTR does not have an OID enabling it to be used in an interoperable with CMS Enveloped data messages; +* **contentToEncrypt** - *ArrayBuffer* - The data to encrypt; + +## Decrypting +To decrypt a message with PKIjs you use the **decrypt** method of **org.pkijs.simpl.CMS_ENVELOPED_DATA** object. + +The **decrypt** method has following parameters: +* **recipientIndex** - *Number* - The index (starting from 0) of the recipient that you want to decrypt the session key for. +> **NOTE:** In **KeyAgreeRecipientInfo** there is possibility to use one ephemeral ECDH key for many different recipients, inside one CMS Enveloped message. This case is not supported by [PKIjs][] - for each new recipient we use new ECDH ephemeral key. That is why [PKIjs][] has no "recipient's sub-indexes"; +* **parameters** - *Object* - The options to be used when decrypting the message; options include: + * **recipientCertificate** - *org.pkijs.simpl.CERT* - This field is mandatory for recipient's type **KeyAgreeRecipientInfo**; + * **recipientPrivateKey** - *ArrayBuffer* - The encoded PKCS#8 structure for recipient's private key. This field is mandatory for recipient's types **KeyTransRecipientInfo** and **KeyAgreeRecipientInfo**; + * **preDefinedData** - *ArrayBuffer* - Early used pre-shared data (pre-shared *"key encryption key"* or password). + +> **NOTE:** [PKIjs][] supports combinations of options not yet (as of April 2015) supported by OpenSSL and Microsoft CryptoAPI (and CNG). For example OpenSSL does not support PBKDF2 with AES-KW algorithms. And Microsoft CryptoAPI does not support **dhSinglePass-stdDH-sha1kdf-scheme** and **dhSinglePass-stdDH-sha512kdf-scheme** or any forms of CMS using pre-shared data. + + +[PKIjs]: http://pkijs.org/ +[FireFox has problems with exporting/importing keys]: https://docs.google.com/spreadsheet/ccc?key=0AiAcidBZRLxndE9LWEs2R1oxZ0xidUVoU3FQbFFobkE#gid=1 +[Google Chrome has no implementation for **DH** at all]: https://sites.google.com/a/chromium.org/dev/blink/webcrypto \ No newline at end of file