Foreword
this article is based on Api12
encryption algorithm is a common business in development. For the sake of security, the client and the server transmit data through encryption, which can ensure the confidentiality of data and prevent sensitive data leakage. In Hongmeng system, encryption algorithm is relatively easy to implement. After all, ArkTs is based on TypeScript, so some algorithms are basically common.
There are many encryption methods, such as symmetric encryption, asymmetric encryption, and Common message digest algorithm MD5,SHA and so on, this article mainly outlines several common algorithms, and simple package after use.
Message Digest Algorithm
message digest algorithm, that is, hash algorithm or one-way hash algorithm, through any length of message, Operation to generate fixed-length summary algorithm, Hongmeng is mainly through. Cryptoframe.createmd method to implement each algorithm.
Currently, the supported algorithms and specifications are as follows:
summary algorithm | types of Support | API version |
---|---|---|
HASH | SHA1 | 9 + |
HASH | SHA224 | 9 + |
HASH | SHA256 | 9 + |
HASH | SHA384 | 9 + |
HASH | SHA512 | 9 + |
HASH | MD5 | 9 + |
HASH | SM3 | 10 + |
take a very simple SHA256 algorithm, other specifications, only need to change the type.
let md = cryptoFramework.createMd("SHA256")
Await md. update ({data: new Uint8Array (buffer. rom, 'utf-8'. buffer)})
let mdResult = await md.digest()
Console.info ('===encrypted result: '+mdResult.data)
let sha256Result = this.uint8ArrayToString(mdResult.data)
Console.info ('===converted to string result:'+sha256Result)
let mdLen = md.getMdLength()
Console.info ("===encrypted length:"+mdLen)
For example, MD5:
let md = cryptoFramework.createMd("MD5")
Await md. update ({data: new Uint8Array (buffer. rom, 'utf-8'. buffer)})
let mdResult = await md.digest()
Console.info ('===encrypted result: '+mdResult.data)
let sha256Result = this.uint8ArrayToString(mdResult.data)
Console.info ('===converted to string result:'+sha256Result)
let mdLen = md.getMdLength()
Console.info ("===encrypted length:"+mdLen)
as can be seen from the above code, the Api provided by the system is basically concise enough.
Base64
in fact, strictly speaking, base64 is not an encryption algorithm, but the corresponding the encoding format is used to represent binary data in the text protocol. By using Base64 encoding, binary data can be converted into printable ACSII characters, that is, Base64 encoding is the process from binary to character, so as to ensure that data is not lost during transmission.
The encoding and decryption of Base64 are also provided in Hongmeng, which is also very simple to use.
// Base64
public base64Encode(str: string): string {
let blob: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(str, 'utf-8').buffer) }
let base64Helper = new util.Base64Helper()
return base64Helper.encodeToStringSync(blob.data)
}
// Base64
public base64Decode(input: string): string {
let base64Helper = new util.Base64Helper()
let uint8Array = base64Helper.decodeSync(input)
return buffer.from(uint8Array).toString("utf-8")
}
AES symmetric encryption
symmetric encryption has a remarkable feature, that is, the encryptor and The Decryptor use the same key. This method has a faster encryption and decryption speed and is suitable for long-term use of data. However, the process of key transmission is not safe and easy to crack. Key management is also troublesome. Common symmetric encryption includes AES,DES, and AES is the most commonly used.
Symmetric encryption AES provides seven encryption modes: ECB, CBC, OFB, CFB, CTR, GCM, and CCM. Different encryption modes apply different encryption and decryption parameters.
Grouping Mode | key length (bit) | fill mode | API version |
---|---|---|---|
ECB | [128 | 192 | 256] |
CBC | [128 | 192 | 256] |
CTR | [128 | 192 | 256] |
OFB | [128 | 192 | 256] |
CFB | [128 | 192 | 256] |
GCM | [128 | 192 | 256] |
CCM | [128 | 192 | 256] |
A simple example of several modes of actual code execution, no matter which way, is to need the secret key and encryption and decryption content, generally we AES development, first to determine the secret key, and then determine the encrypted content and decryption content.
ECB mode, encryption and decryption
async encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('AES128|ECB|PKCS7');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);
let cipherData = await cipher.doFinal(plainText);
return cipherData;
}
async decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher('AES128|ECB|PKCS7');
await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null);
let decryptData = await decoder.doFinal(cipherText);
re
GCM mode, encryption and decryption
genGcmParamsSpec() {
let ivBlob = this.generateRandom(12);
let arr = [1, 2, 3, 4, 5, 6, 7, 8]; // 8 bytes
let dataAad = new Uint8Array(arr);
let aadBlob: cryptoFramework.DataBlob = { data: dataAad };
arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
let dataTag = new Uint8Array(arr);
let tagBlob: cryptoFramework.DataBlob = {
data: dataTag
};
//The authTag of GCM is obtained from the doFinal result during encryption and filled into the params parameter of the init function during decryption
let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {
iv: ivBlob,
aad: aadBlob,
authTag: tagBlob,
algName: "GcmParamsSpec"
};
return gcmParamsSpec;
}
gcmParams = this.genGcmParamsSpec();
//Encrypt messages
async encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('AES128|GCM|PKCS7');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, this.gcmParams);
let encryptUpdate = await cipher.update(plainText);
//When encrypting doFinal in gcm mode, pass in empty space, obtain tag data, and update it to the gcmParams object.
this.gcmParams.authTag = await cipher.doFinal(null);
return encryptUpdate;
}
//Decrypt message
async decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher('AES128|GCM|PKCS7');
await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, this.gcmParams);
let decryptUpdate = await decoder.update(cipherText);
//When decrypting doFinal in gcm mode, empty data is passed in. When verifying init, tag data is passed in. If verification fails, an exception will be thrown.
let decryptData = await decoder.doFinal(null);
if (decryptData == null) {
console.info('GCM decrypt success, decryptData is null');
}
return decryptUpdate;
}
CCM mode, encryption and decryption
genCcmParamsSpec() {
let rand: cryptoFramework.Random = cryptoFramework.createRandom();
let ivBlob: cryptoFramework.DataBlob = rand.generateRandomSync(7);
let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8);
let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes
let dataTag = new Uint8Array(arr);
let tagBlob: cryptoFramework.DataBlob = {
data: dataTag
};
//CCM's authTag is obtained from the doFinal result during encryption and filled into the params parameter of the init function during decryption
let ccmParamsSpec: cryptoFramework.CcmParamsSpec = {
iv: ivBlob,
aad: aadBlob,
authTag: tagBlob,
algName: "CcmParamsSpec"
};
return ccmParamsSpec;
}
ccmParams = this.genCcmParamsSpec();
//Encrypt messages
async encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('AES128|CCM');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, this.ccmParams);
let encryptUpdate = await cipher.update(plainText);
//When encrypting doFinal in CCM mode, pass in empty space, obtain tag data, and update it to the ccmParams object.
this.ccmParams.authTag = await cipher.doFinal(null);
return encryptUpdate;
}
//Decrypt message
async decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher('AES128|CCM');
await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, this.ccmParams);
let decryptUpdate = await decoder.doFinal(cipherText);
return decryptUpdate;
}
in actual development, we can generate our secret key according to the provided string or other specific characters, generally in the form of a string key after Base64 encoding, and then decode it when encrypting and decrypting.
RSA asymmetric encryption
the difference between asymmetric encryption and symmetric encryption is that it has two secret keys, a public key and a private key. The public key is used for encryption and the private key is used for decryption. Compared with symmetric encryption, the security factor is on a higher level, but there is also the risk of man-in-the-middle attack. Common asymmetric encryption includes RSA,DSA,ECC, etc. Generally, the most commonly used is RSA.
RSA also provides a variety of encryption methods, such as PKCS1 mode PKCS1_OAEP mode, and NoPadding.
PKCS1 mode
async encryptMessagePromise(publicKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
let encryptData = await cipher.doFinal(plainText);
return encryptData;
}
async decryptMessagePromise(privateKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');
await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, privateKey, null);
let decryptData = await decoder.doFinal(cipherText);
return decryptData;
}
Other modes, no longer examples, you can go to the official website to check.
Encapsulation Use
you can use the above methods to encrypt and decrypt the data. Of course, you can also package it yourself or use someone else's package. For the above, I also simply packaged it, and friends who need it can use it.
Simple Feature List
quick Use
method 1: in the Terminal window, run the following command to install the third-party package. DevEco Studio automatically adds the third-party package dependency to the project oh-package.json5.
Suggestion: Execute the command under the module path used.
ohpm install @abner/security
Method 2: Set the three-party package dependency in the project oh-package.json5. The configuration example is as follows:
"dependencies": { "@abner/security": "^1.0.0"}
code Use
1, MD5
synchronization
Let encryptContent=md5EncryptSync ("encrypted data")
Console.log ("===encrypted:"+encryptContent)
asynchronous
Md5Encrypt ("encrypted data"). then ((content)=>{
Console.log ("===encrypted:"+content)
})
2, BASE64
code synchronization
Let encryptContent=base64EncodeSync ("I am test data")
this.mBase64EncodeString = encryptContent
Console.log ("===encoded:"+encryptContent)
coding asynchronous
Base64Encode ("I am test data"). then ((encryptContent)=>{
this.mBase64EncodeString = encryptContent
Console.log ("===encoded:"+encryptContent)
})
decode synchronization
base64Decode(this.mBase64EncodeString).then((decode) => {
Console.log ("===decoded:"+decode)
})
3, SHA
the default sha is SHA256, which can be modified as needed. Just pass in the second parameter.
Synchronization
let encryptContent = shaEncryptSync("1")
asynchronous
shaEncrypt("1").then((content) => {
})
modify the algName
let encryptContent = shaEncryptSync("1","SHA256")
4. SM3
synchronization
Let encryptContent=sM3EncryptSync ("encrypted data")
Console.log ("===encrypted:"+encryptContent)
asynchronous
SM3Encrypt ("encrypted data"). then ((content)=>{
Console.log ("===encrypted:"+content)
})
5, AES
randomly generate SymKey [asynchronous]]
aesGenerateSymKey().then((symKey) => {
this.mSymKey = symKey
Console.log (===Key:+symKey)
})
randomly generate SymKey key [synchronization]]
let symKey = aesGenerateSymKeySync()
this.mSymKey = symKey
Console.log (===Key:+symKey)
string Generation Key [Asynchronous]]
aesGenerateSymKey("1234").then((symKey) => {
this.mSymKey = symKey
})
string Generation Key [Sync]]
let symKeyString = aesGenerateSymKeySync("1234")
this.mSymKey = symKeyString
encrypted data [asynchronous] [ECB mode]]
aesEncryptString("123", this.mSymKey).then((result) => {
this.encryptString = result
})
decryption data [asynchronous] [ECB mode]]
aesDecryptString(this.encryptString, this.mSymKey).then((result) => {
})
encrypted data [synchronization] [ECB mode]]
let result = aesEncryptStringSync("123", this.mSymKey)
this.encryptString = result
decryption data [synchronization] [ECB mode]]
let decryptString = aesDecryptStringSync(this.encryptString!, this.mSymKey!)
6. RSA
randomly generate KeyPair [asynchronous]]
rsaGenerateAsyKey().then((keyPair) => {
let pubKey = keyPair.pubKey
let priKey = keyPair.priKey
this.priKey = priKey
this.pubKey = pubKey
})
randomly generate KeyPair [synchronization]]
let keyPair = rsaGenerateAsyKeySync()
let pubKey1 = keyPair.pubKey
let priKey1 = keyPair.priKey
this.priKey = priKey1
this.pubKey = pubKey1
randomly Generate String Key Pair [Asynchronous]]
rsaGenerateAsyKeyPem().then((keyPairPem) => {
let pubKey = keyPairPem.pubKey
let priKey = keyPairPem.priKey
})
randomly Generate String Key Pair [Synchronization]]
let keyPairPem = generateAsyKeyPemSync()
let pubKeyPem = keyPairPem.pubKey
let priKeyPem = keyPairPem.priKey
randomly generated key pair binary [asynchronous]]
rsaGenerateAsyKeyDataBlob().then((dataBlobArray) => {
let pubKey: cryptoFramework.DataBlob = dataBlobArray[0]
let priKey: cryptoFramework.DataBlob = dataBlobArray[1]
})
randomly Generated Binary Key Pair [Synchronization]]
let dataBlobArray = rsaGenerateAsyKeyDataBlobSync()
let pubKey: cryptoFramework.DataBlob = dataBlobArray[0]
let priKey: cryptoFramework.DataBlob = dataBlobArray[1]
generate KeyPair key pair by specifying binary data [asynchronous]]
rsaGenKeyPairByData(this.pkData, this.skData).then((keyPair) => {
let pubKey = keyPair.pubKey
let priKey = keyPair.priKey
this.priKey = priKey
this.pubKey = pubKey
})
generate KeyPair key pair by specifying binary data [synchronization]]
let keyPairByDataSync = rsaGenKeyPairByDataSync(this.pkData, this.skData)
let pubKeyPairByData = keyPairByDataSync.pubKey
let priKeyPairByData = keyPairByDataSync.priKey
this.priKey = priKeyPairByData
this.pubKey = pubKeyPairByData
generating String Key Pairs from Binary Data [Asynchronous]]
rsaGenKeyPairByDataPem(this.pkData, this.skData).then((keyPairPem) => {
let pubKeyPem = keyPairPem.pubKey
let priKeyPem = keyPairPem.priKey
})
generate String Key Pair from Binary Data [Synchronization]]
let keyPairByDataPemSync = rsaGenKeyPairByDataPemSync(this.pkData, this.skData)
let pubKeyPairByDataPem = keyPairByDataPemSync.pubKey
let priKeyPairByDataPem = keyPairByDataPemSync.priKey
string data generation KeyPair [asynchronous]]
rsaGenKeyPairString(this.appRsaPublicKey, this.appRsaPrivateKey).then((keyPair) => {
let pubKey = keyPair.pubKey
let priKey = keyPair.priKey
this.priKey = priKey
this.pubKey = pubKey
})
string data generation KeyPair [synchronization]]
let keyPair2 = rsaGenKeyPairStringSync(this.publicPkcs1Str1024, this.priKeyPkcs1Str1024)
let pubKey3 = keyPair2.pubKey
let priKey3 = keyPair2.priKey
this.priKey = priKey3
this.pubKey = pubKey3
string data generation string key pair [asynchronous]]
rsaGenKeyPairStringPem(this.appRsaPublicKey, this.appRsaPrivateKey).then((keyPair) => {
let pubKeyPem = keyPair.pubKey
let priKeyPem = keyPair.priKey
})
String data generation string key pair [synchronization]]
let keyPairStringPemSync = rsaGenKeyPairStringPemSync(this.publicPkcs1Str1024, this.priKeyPkcs1Str1024)
let pubKeyPairStringPemSync = keyPairStringPemSync.pubKey
let priKeyPairStringPemSync = keyPairStringPemSync.priKey
string key encryption [asynchronous]]
Let message="I am a piece of data that needs to be encrypted"
Console.log ("===Data before encryption:"+message)
rsaEncryptString(message, this.publicKey).then((data) => {
this.encryptString = data
Console.log ("===encrypted data:"+data)
}).catch((e: BusinessError) => {
Console.log ("===Encryption Error:"+JSON. stringify (e.message))
})
string Key Mode Decryption [Asynchronous]]
//There must be a private key and the data to be decrypted
rsaDecryptString(this.encryptString, this.privateKey).then((data) => {
Console.log ("==decrypted data:"+data)
})
string key encryption [synchronization]]
Let message1="I am a piece of data that needs to be encrypted"
Console.log ("===Data before encryption:"+message1)
this.encryptString = rsaEncryptStringSync(message1, this.publicKey)
Console.log ("===encrypted data:"+this. encryptString)
string Key Mode Decryption [Synchronization]]
//There must be a private key and the data to be decrypted
let data = rsaDecryptStringSync(this.encryptString, this.privateKey)
Console.log ("==decrypted data:"+data)
encryption KeyPair key method [asynchronous] requires cryptoFramework.PubKey
if (this.pubKey != undefined) {
Let message="I am a piece of data that needs to be encrypted"
Console.log ("===Data before encryption:"+message)
rsaEncryptDataBlob(message, this.pubKey!).then((data) => {
this.encryptDataBlob = data
Console.log ("===encrypted data:"+JSON. stringify (data))
}).catch((e: BusinessError) => {
Console.log ("===Encryption Error:"+JSON. stringify (e.message))
})
}
decrypt KeyPair key method [asynchronous]]
if (this.priKey != undefined && this.encryptDataBlob != undefined) {
//There must be a private key and the data to be decrypted
rsaDecryptDataBlob(this.encryptDataBlob, this.priKey).then((data) => {
Console.log ("==decrypted data:"+data)
})
}
encryption KeyPair key mode [synchronization]]
if (this.pubKey != undefined) {
Let message1="I am a piece of data that needs to be encrypted"
Console.log ("===Data before encryption:"+message1)
this.encryptDataBlob = rsaEncryptDataBlobSync(message1, this.pubKey!)
Console.log ("===encrypted data:"+JSON. stringify (this. encryptDataBlob))
}
decrypt KeyPair key mode [synchronization]]
if (this.priKey != undefined && this.encryptDataBlob != undefined) {
//There must be a private key and the data to be decrypted
let data = rsaDecryptDataBlobSync(this.encryptDataBlob, this.priKey)
Console.log ("==decrypted data:"+data)
}
private key signature synchronization
let sign = rsaEncryptPriKeyContentSync("123", this.privateKey)
Console.log ("======Signature:"+sign)
public Key Signature Verification Synchronization
//This. signData is the signature content
let signResult = rsaDecryptPubKeyContentSync("123",this.signData, this.publicKey)
Console.log ("=====signature verification:"+signResult)
private key signing asynchronous
rsaEncryptPriKeyContent("123", this.privateKey).then((sign) => {
Console.log ("======Signature:"+sign)
})
public Key Signature Verification Asynchronous
rsaEncryptPriKeyContent("123", this.privateKey).then((sign) => {
Console.log ("======Signature:"+sign)
})
Top comments (0)