> This guide applies to JS development using OpenHarmony API version 9 and SDK version 3.2.7 or later.
## Generating and Converting a Key
## Key Generation and Conversion
**When to Use**
### When to Use
Typical key generation operations involve the following:
1. Randomly create a key instance for subsequent encryption and decryption.
2. Convert external or stored binary data into a key instance for subsequent encryption and decryption.
3. Obtain the binary data of a key for storage or transmission.
1. Randomly create a key object for subsequent encryption and decryption.
2. Convert external or internal binary data into a key object for subsequent encryption and decryption.
3. Obtain the binary data of a key object for storage or transmission.
> **NOTE**<br>The key instance can be a symmetric key instance (**SymKey**) or an asymmetric key pair instance (**KeyPair**). The **KeyPair** instance consists a public key (**PubKey**) and a private key (**PriKey**). For details about the relationship between keys, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
**Available APIs**
### Available APIs
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
The table below describes the APIs used in this guide.
The following table describes the APIs used in this guide. For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
|Instance|API|Description|
|---|---|---|
|cryptoFramework|createAsyKeyGenerator(algName : string) : AsyKeyGenerator|Creates an **AsyKeyGenerator** instance.|
|cryptoFramework|createAsyKeyGenerator(algName : string) : AsyKeyGenerator|Creates an **AsyKeyGenerator** instance based on the asymmetric key pair specifications specified by **algName**.|
|cryptoFramework|createSymKeyGenerator(algName : string) : SymKeyGenerator|Creates a **SymKeyGenerator** instance.|
|AsyKeyGenerator|generateKeyPair(callback : AsyncCallback\<KeyPair>) : void|Generates an asymmetric key pair randomly. This API uses an asynchronous callback to return the result.|
|AsyKeyGenerator|generateKeyPair() : Promise\<KeyPair>|Generates an asymmetric key pair randomly. This API uses a promise to return the result.|
...
...
@@ -36,15 +34,15 @@ The table below describes the APIs used in this guide.
| SymKeyGenerator |convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\<KeyPair>| Converts binary data into a symmetric key. This API uses a promise to return the result.|
| Key | getEncoded() : DataBlob; | Obtains the binary data of a key. (The child class instances of **Key** include **SymKey**, **PubKey**, and **PriKey**.)|
**How to Develop**
### How to Develop
Example 1: Randomly generate an asymmetric key pair and obtain its binary data.
Randomly generate an asymmetric key pair and obtain its binary data.
1. Create an **AsyKeyGenerator** instance.
2. Randomly generate an asymmetric key pair using **AsyKeyGenerator**.
3. Obtain binary data of the key pair generated.
3. Obtain the binary data of the key pair generated.
The following sample code demonstrates how to randomly generate an RSA key (1024 bits and two primes) using promise-based APIs.
Example: Randomly generate an RSA key (1024 bits and two primes) in promise mode.
@@ -98,10 +96,10 @@ function testGenerateAesKey() {
}
```
Example 3: Generate an asymmetric key pair from the binary RSA key data.
Generate an RSA asymmetric key pair from the binary data.
1. Obtain the binary data of the RSA public or private key. The public key must comply with the ASN.1 syntax, X.509 specifications, and DER encoding format. The private key must comply with the ASN.1 syntax, PKCS #8 specifications, and DER encoding format.
2. Create an **AsyKeyGenerator** instance and call**convertKey()** to convert the key binary data (data of the private or public key, or both) into a **KeyPair** instance.
2. Create an **AsyKeyGenerator** instance, and use**convertKey()** to convert the key binary data (data of the private or public key, or both) into a **KeyPair** instance.
> The public key material to be converted in **convertKey()** must be in the DER format complying with X.509 specifications, and the private key material must be in the DER format complying with PKCS #8 specifications.
> The public key binary data to be converted by **convertKey()** must be in the DER format complying with X.509 specifications, and the private key binary data must be in the DER format complying with PKCS #8 specifications.
Example 4: Generate an asymmetric key pair from the binary ECC key data.
Generate an ECC asymmetric key pair from the binary key data.
1. Obtain the ECC binary key data and encapsulate it into a **DataBlob** instance.
2. Call **convertKey()** to convert the key binary data (data of the private or public key, or both) into a **KeyPair** instance.
2. Call **convertKey()** to convert the binary data (data of the private or public key, or both) into a **KeyPair** instance.
Important data needs to be encrypted in data storage or transmission for security purposes. Typical encryption and decryption operations involve the following:
1. Encrypt and decrypt data using a symmetric key.
2. Encrypt and decrypt data using an asymmetric key pair.
**Available APIs**
### Available APIs
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md). <br>Due to the complexity of cryptographic algorithms, the implementation varies depending on the specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs in the API reference to ensure correct use of these APIs.
The table below describes the APIs used in this guide.
The following table describes the APIs used in this guide. For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md). <br>Due to complexity of cryptographic algorithms, the implementation varies depending on the specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs to ensure correct use of these APIs.
|Instance|API|Description|
|---|---|---|
...
...
@@ -220,16 +218,16 @@ The table below describes the APIs used in this guide.
|Cipher|doFinal(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|Finalizes the encryption or decryption. This API uses an asynchronous callback to return the result.|
|Cipher|doFinal(data : DataBlob) : Promise\<DataBlob>|Finalizes the encryption or decryption. This API uses a promise to return the result.|
**How to Develop**
### How to Develop
Example 1: Encrypt and decrypt data using a symmetric key.
Encrypt and decrypt data using a symmetric key.
1. Create a **SymKeyGenerator** instance.
2. Use the key generator to generate a symmetric key.
3. Create a **Cipher** instance.
4. Encrypt or decrypt data.
The following example demonstrates how to use the AES-GCM to encrypt and decrypt data with promise-based APIs.
Example: Use AES GCM to encrypt and decrypt data in promise mode.
The following example demonstrates how to use the the 3DES ECB to convert existing data into a key and encrypt and decrypt data using callback-based APIs.
Example: Generate a key from the existing data to encrypt and decrypt data using 3DES ECB in callback mode.
@@ -738,7 +736,7 @@ function decryptMessageCallback() {
});
}
```
The following example demonstrates how to implement RSA asymmetric encryption and decryption (**doFinal()** is called multiple times).
Example: Use an RSA asymmetric key pair to encrypt and decrypt data. In this example, **doFinal()** is called multiple times to process data by segment.
@@ -823,23 +821,23 @@ function encryptLongMessagePromise() {
}
```
> **NOTE**
>
> - In RSA encryption and decryption, **init()** cannot be repeatedly called to initialize the **Cipher** instance. You must create a **Cipher** instance for each encryption and decryption.
> - The RSA encryption has a limit on the length of the plaintext to be encrypted. For details, see "Basic Concepts" in [Cryptographic Framework Overview](cryptoFramework-overview.md).
> - In RSA decryption, the length of the ciphertext to be decrypted each time is the number of bits of the RSA key divided by 8.
**NOTE**
- In RSA encryption and decryption, **init()** cannot be repeatedly called to initialize a**Cipher** instance. You must create a **Cipher** instance for each encryption and decryption.
- The RSA encryption has a limit on the length of the plaintext to be encrypted. For details, see "Basic Concepts" in [Cryptographic Framework Overview](cryptoFramework-overview.md).
- In RSA decryption, the length of the ciphertext to be decrypted each time is the number of bits of the RSA key divided by 8.
## Generating and Verifying a Signature
## Signing and Signature Verification
**When to Use**
### When to Use
A digital signature can be used to verify the authenticity of a message. Typical signing and signature verification operations involve the following:
- Use the RSA to generate and verify a signature.
- Use the ECC to generate and verify a signature.
1. Use RSA to generate a signature and verify the signature.
2. Use ECC to generate a signature and verify the signature.
**Available APIs**
### Available APIs
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md). <br>Due to the complexity of cryptographic algorithms, the implementation varies depending on the specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs in the API reference to ensure correct use of these APIs.
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md). <br>Due to complexity of cryptographic algorithms, the implementation varies depending on the specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs to ensure correct use of these APIs.
|Instance|API|Description|
|---|---|---|
...
...
@@ -855,17 +853,17 @@ For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cry
|Verify|init(priKey : PriKey) : Promise\<void>|Sets a key and initializes the **Verify** instance. This API uses a promise to return the result.|
|Verify|update(data : DataBlob, callback : AsyncCallback\<void>) : void|Updates the data for signature verification. This API uses an asynchronous callback to return the result.|
|Verify|update(data : DataBlob) : Promise\<void>|Updates the data for signature verification. This API uses a promise to return the result.|
|Verify|verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\<boolean>) : void|Verifies the signature. This API uses an asynchronous callback to return the result.|
|Verify|verify(data : DataBlob, signatureData : DataBlob) : Promise\<boolean>|Verifies the signature. This API uses a promise to return the result.|
|Verify|verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\<boolean>) : void|Verifies a signature. This API uses an asynchronous callback to return the result.|
|Verify|verify(data : DataBlob, signatureData : DataBlob) : Promise\<boolean>|Verifies a signature. This API uses a promise to return the result.|
**How to Develop**
### How to Develop
Example 1: Use the RSA to generate and verify a signature.
Use RSA to sign data and verify the signature.
1. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
2. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
3. Generate a signature.<br>Call **update()** provided by the **Sign** class to add the data for signing and call **sign()** to generate a signature.
3. Generate a signature.<br>Call **update()** provided by the **Sign** class to pass in the data for signing and call **sign()** to generate a signature.
4. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
5. Verify the signature.<br>Call **update()** provided by the **Verify** class to add signature data and call **verify()** to verify the signature.
5. Verify the signature.<br>Call **update()** provided by the **Verify** class to pass in the signature data and call **verify()** to verify the signature.
@@ -944,12 +942,12 @@ function verifyMessageCallback() {
}
```
Example 2: Use the ECDSA to generate and verify a signature.
Use ECDSA to sign data and verify the signature.
1. Generate an ECC key.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an ECC asymmetric key pair.
2. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
3. Generate a signature.<br>Call **update()** provided by the **Sign** class to add the data for signing and call **doFinal()** to generate a signature.
3. Generate a signature.<br>Call **update()** provided by the **Sign** class to pass in the data for signing and call **doFinal()** to generate a signature.
4. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
5. Verify the signature.<br>Call **update()** provided by the **Verify** class to add signature data and call **doFinal()** to verify the signature.
5. Verify the signature.<br>Call **update()** provided by the **Verify** class to pass in the signature data and call **doFinal()** to verify the signature.
@@ -1056,16 +1055,16 @@ function signLongMessagePromise() {
letcipherAlgName="RSA1024|PKCS1|SHA256";
letglobalKeyPair;
letasyKeyGenerator=cryptoFramework.createAsyKeyGenerator(keyGenName);// Create an AsyKeyGenerator object.
letsigner=cryptoFramework.createSign(cipherAlgName);//Create a cipher object for encryption.
letverifier=cryptoFramework.createVerify(cipherAlgName);// Create a Decoder object for decryption.
letsigner=cryptoFramework.createSign(cipherAlgName);//Create a Sign object for signing.
letverifier=cryptoFramework.createVerify(cipherAlgName);// Create a Verify object for signature verification.
returnnewPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("testRsaMultiUpdate");
},10);
}).then(()=>{
returnasyKeyGenerator.generateKeyPair();// Generate an RSA key.
returnasyKeyGenerator.generateKeyPair();// Generate an RSA key pair.
}).then(keyPair=>{
globalKeyPair=keyPair;// Save the key to global variables.
globalKeyPair=keyPair;// Save the key pair as a global variable.
returnsigner.init(globalKeyPair.priKey);
}).then(async()=>{
// If the plaintext is too large, split the plaintext based on the specified length and cyclically call update() to pass in the plaintext.
...
...
@@ -1095,11 +1094,11 @@ function signLongMessagePromise() {
}
```
## Generating a Digest
## Message Digest
**When to Use**
### When to Use
A message digest (MD) is a fixed size numeric representation of the content of a message, computed by a has function. It is sent with the message. The receiver can generate a digest for the message and compare it with the digest received. If the two digests are the same, the message integrity is verified.
A message digest (MD) is a fixed size numeric representation of the content of a message, computed by a hash function. It is sent with the message. The receiver can generate a digest for the message and compare it with the digest received. If the two digests are the same, the message integrity is verified.
Typical MD operations involve the following:
...
...
@@ -1108,7 +1107,7 @@ Typical MD operations involve the following:
3. Compute a digest.
4. Obtain the algorithm and length of a digest.
**Available APIs**
### Available APIs
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
...
...
@@ -1122,162 +1121,153 @@ For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cry
| Md | getMdLength() : number; | Obtains the digest length based on the specified digest algorithm. |
Key agreement allows two parties to establish a shared secret over an insecure channel.
**Available APIs**
### Available APIs
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
...
...
@@ -1287,9 +1277,9 @@ For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cry
|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\<DataBlob>) : void|Generates a shared secret. This API uses an asynchronous callback to return the result.|
|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\<DataBlob>|Generates a shared secret. This API uses a promise to return the result.|
**How to Develop**
### How to Develop
1. Use **createKeyAgreement()** to create a **KeyAgreement**object for subsequent key agreement operations.
1. Use **createKeyAgreement()** to create a **KeyAgreement**instance for subsequent key agreement operations.
2. Use **generateSecret()** provided by **KeyAgreement** to pass in the peer ECC public key object and the ECC private key object generated locally.
```javascript
...
...
@@ -1337,27 +1327,27 @@ function ecdhCallback() {
}
```
## Generating a MAC
## HMAC
**When to Use**
### When to Use
A message authentication code (MAC) can be used to verify both the integrity and authenticity of a message using a shared secret.
A hash-based message authentication code (HMAC) can be used to verify both the integrity and authenticity of a message using a shared secret.
Typical MAC operations involve the following:
1. Create a **Mac** instance.
2. Initialize the **Mac** instance, add one or more segments of data for generating a MAC, and generate aMAC.
3. Obtain the algorithm and length of aMAC.
2. Initialize the **Mac** instance, add one or more segments of data for generating a MAC, and generate an HMAC.
3. Obtain the algorithm and length of an HMAC.
**Available APIs**
### Available APIs
For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
| cryptoFramework | function createMac(algName : string) : Mac; | Creates a **Mac** instance. |
| Mac | init(key : SymKey, callback : AsyncCallback\<void>) : void; | Initializes the MAC operation. This API uses an asynchronous callback to return the result.|
| Mac | init(key : SymKey) : Promise\<void>; | Initializes the MAC operation. This API uses a promise to return the result. |
| Mac | init(key : SymKey, callback : AsyncCallback\<void>) : void; | Initializes the **Mac** instance. This API uses an asynchronous callback to return the result.|
| Mac | init(key : SymKey) : Promise\<void>; | Initializes the **Mac** instance. This API uses a promise to return the result. |
| Mac | update(input : DataBlob, callback : AsyncCallback\<void>) : void; | Updates the data for the MAC operation. This API uses an asynchronous callback to return the result. |
| Mac | update(input : DataBlob) : Promise\<void>; | Updates the data for the MAC operation. This API uses a promise to return the result. |
| Mac | doFinal(callback : AsyncCallback\<DataBlob>) : void; | Finalizes the MAC operation to generate a MAC. This API uses an asynchronous callback to return the result. |
...
...
@@ -1365,7 +1355,7 @@ For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cry
| Mac | getMacLength() : number; | Obtains the length of the MAC based on the specified algorithm. |
| Mac | readonly algName : string; | Obtains the digest algorithm. |
**How to Develop**
### How to Develop
1. Call **createMac()** to create a **Mac** instance.
2. Call **init()** to initialize the **Mac** instance with the symmetric key passed in.
...
...
@@ -1376,77 +1366,72 @@ For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cry