Signing and Signature Verification by Segment with an RSA Key Pair (PKCS1 Mode) (ArkTS)
For details about the algorithm specifications, see RSA.
Signing
-
Call cryptoFramework.createAsyKeyGenerator and AsyKeyGenerator.generateKeyPair to generate a 1024-bit RSA key pair (KeyPair) with two primes. The KeyPair instance consists of a public key (PubKey) and a private key (PriKey).
In addition to the example in this topic, RSA and Randomly Generating an Asymmetric Key Pair may help you better understand how to generate an RSA asymmetric key pair. Note that the input parameters in the reference documents may be different from those in the example below.
-
Call cryptoFramework.createSign with the string parameter RSA1024|PKCS1|SHA256 to create a Sign instance. The asymmetric key type is RSA1024, the padding mode is PKCS1, and the MD algorithm is SHA256.
-
Call Sign.init to initialize the Sign instance with the private key (PriKey).
-
Set the data length to be passed in each time to 64 bytes, and call Sign.update multiple times to pass in the data to be signed. Currently, the amount of data to be passed in by a single update is not limited. You can determine how to pass in data based on the data volume.
-
Call Sign.sign to generate a signature.
Signature Verification
-
Call cryptoFramework.createVerify with the string parameter 'RSA1024|PKCS1|SHA256' to create a Verify instance. The string parameter must be the same as that used to create the Sign instance.
-
Call Verify.init to initialize the Verify instance with the public key (PubKey).
-
Call Verify.update to pass in the data to be verified. Currently, the amount of data to be passed in by a single update is not limited. You can determine how to pass in data based on the data volume.
-
Call Verify.verify to verify the data signature.
-
Example (using asynchronous APIs):
import { cryptoFramework } from '@kit.CryptoArchitectureKit'; import { buffer } from '@kit.ArkTS'; async function signMessageBySegment(priKey: cryptoFramework.PriKey, plainText: Uint8Array) { let signAlg = 'RSA1024|PKCS1|SHA256'; let signer = cryptoFramework.createSign(signAlg); await signer.init(priKey); let textSplitLen = 64; // Set the length of the data to be passed each time. In this example, the value is 64. for (let i = 0; i < plainText.length; i += textSplitLen) { let updateMessage = plainText.subarray(i, i + textSplitLen); let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; // Segmented update. await signer.update(updateMessageBlob); } // Pass null here because all the plaintext has been passed by segment. let signData = await signer.sign(null); return signData; } async function verifyMessageBySegment(pubKey: cryptoFramework.PubKey, plainText: Uint8Array, signMessageBlob: cryptoFramework.DataBlob) { let verifyAlg = 'RSA1024|PKCS1|SHA256'; let verifier = cryptoFramework.createVerify(verifyAlg); await verifier.init(pubKey); let textSplitLen = 64; // Set the length of the data to be passed each time. In this example, the value is 64. for (let i = 0; i < plainText.length; i += textSplitLen) { let updateMessage = plainText.subarray(i, i + textSplitLen); let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; // Segmented update. await verifier.update(updateMessageBlob); } // Pass null in the first parameter of verify() because all the plaintext has been passed by segment. let res = await verifier.verify(null, signMessageBlob); console.info('verify result: ' + res); return res; } async function rsaSignatureBySegment() { let message = 'This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!'; let keyGenAlg = 'RSA1024'; let generator = cryptoFramework.createAsyKeyGenerator(keyGenAlg); let keyPair = await generator.generateKeyPair(); let messageData = new Uint8Array(buffer.from(message, 'utf-8').buffer); let signData = await signMessageBySegment(keyPair.priKey, messageData); let verifyResult = await verifyMessageBySegment(keyPair.pubKey, messageData, signData); if (verifyResult === true) { console.info('verify result: success.'); } else { console.error('verify result: failed.'); } } -
Example (using synchronous APIs):
import { cryptoFramework } from '@kit.CryptoArchitectureKit'; import { buffer } from '@kit.ArkTS'; function signMessageBySegment(priKey: cryptoFramework.PriKey, plainText: Uint8Array) { let signAlg = 'RSA1024|PKCS1|SHA256'; let signer = cryptoFramework.createSign(signAlg); signer.initSync(priKey); let textSplitLen = 64; // Set the length of the data to be passed each time. In this example, the value is 64. for (let i = 0; i < plainText.length; i += textSplitLen) { let updateMessage = plainText.subarray(i, i + textSplitLen); let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; // Segmented update. signer.updateSync(updateMessageBlob); } // Pass null here because all the plaintext has been passed by segment. let signData = signer.signSync(null); return signData; } function verifyMessageBySegment(pubKey: cryptoFramework.PubKey, plainText: Uint8Array, signMessageBlob: cryptoFramework.DataBlob) { let verifyAlg = 'RSA1024|PKCS1|SHA256'; let verifier = cryptoFramework.createVerify(verifyAlg); verifier.initSync(pubKey); let textSplitLen = 64; // Set the length of the data to be passed each time. In this example, the value is 64. for (let i = 0; i < plainText.length; i += textSplitLen) { let updateMessage = plainText.subarray(i, i + textSplitLen); let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; // Segmented update. verifier.updateSync(updateMessageBlob); } // Pass null in the first parameter of verify() because all the plaintext has been passed by segment. let res = verifier.verifySync(null, signMessageBlob); console.info('verify result: ' + res); return res; } function rsaSignatureBySegment() { let message = 'This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!' + 'This is a long plainText! This is a long plainText! This is a long plainText! This is a long plainText!'; let keyGenAlg = 'RSA1024'; let generator = cryptoFramework.createAsyKeyGenerator(keyGenAlg); let keyPair = generator.generateKeyPairSync(); let messageData = new Uint8Array(buffer.from(message, 'utf-8').buffer); let signData = signMessageBySegment(keyPair.priKey, messageData); let verifyResult = verifyMessageBySegment(keyPair.pubKey, messageData, signData); if (verifyResult === true) { console.info('verify result: success.'); } else { console.error('verify result: failed.'); } }