• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用RSA密钥对签名验签(PSS模式)(ArkTS)
2
3对应的算法规格请查看[签名验签算法规格:RSA](crypto-sign-sig-verify-overview.md#rsa)。
4
5**签名**
6
71. 调用[cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10)、[AsyKeyGeneratorBySpec.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-3),指定密钥参数,生成RSA非对称密钥对(KeyPair)。
8   如何生成RSA非对称密钥,开发者可参考下文示例,并结合[非对称密钥生成和转换规格:RSA](crypto-asym-key-generation-conversion-spec.md#rsa)和[指定密钥参数生成非对称密钥对](crypto-generate-asym-key-pair-from-key-spec.md)理解,参考文档与当前示例可能存在入参差异,请在阅读时注意区分。
9
102. 调用[cryptoFramework.createSign](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatesign),指定字符串参数'RSA|PSS|SHA256|MGF1_SHA256',创建非对称密钥类型为不带长度的RSA、填充模式为PSS、摘要算法为SHA256、掩码算法为MGF1_SHA256的Sign实例,用于完成签名操作。
11
123. 调用[Sign.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-3),使用私钥(PriKey)初始化Sign实例。
13
144. 调用[Sign.setSignSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#setsignspec10),设置签名参数。此处设置盐值的长度(SignSpecItem.PSS_SALT_LEN_NUM)为32字节。在验签时将校验此数据。
15
165. 调用[Sign.getSignSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getsignspec10),获取其他签名参数。
17
186. 调用[Sign.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-3),传入待签名的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。
19
207. 调用[Sign.sign](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#sign-1),生成数据签名。
21
22**验签**
23
241. 调用[cryptoFramework.createVerify](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateverify),指定字符串参数'RSA2048|PSS|SHA256|MGF1_SHA256',创建非对称密钥类型为RSA2048、填充模式为PSS、摘要算法为SHA256、掩码算法为MGF1_SHA256的Verify实例,用于完成验签操作。
25
262. 调用[Verify.setVerifySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#setverifyspec10),设置签名参数。需要与签名时设置的保持一致。
27
283. 调用[Verify.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-5),使用公钥(PubKey)初始化Verify实例。
29
304. 调用[Verify.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-5),传入待验证的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。
31
325. 调用[Verify.verify](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#verify-1),对数据进行验签。
33
34- 异步方法示例:
35
36  ```ts
37  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
38  import { buffer } from '@kit.ArkTS';
39  // 根据密钥参数属性构造RSA非对称密钥对密钥参数。
40  function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) {
41    let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
42      n: nIn,
43      algName: "RSA",
44      specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
45    };
46    let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = {
47      params: rsaCommSpec,
48      sk: dIn,
49      pk: eIn,
50      algName: "RSA",
51      specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC
52    };
53    return rsaKeyPairSpec;
54  }
55  // 生成RSA2048密钥对参数。
56  function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec {
57    let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
58    let eIn = BigInt("0x010001");
59    let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1");
60    return genRsaKeyPairSpec(nIn, eIn, dIn);
61  }
62
63  async function verifyMessagePSS() {
64    // 完整的明文被拆分为input1和input2。
65    let plan1 = "This is Sign test plan1";
66    let plan2 = "This is Sign test plan2";
67    let input1: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(plan1, 'utf-8').buffer) };
68    let input2: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(plan2, 'utf-8').buffer) };
69    // 获得RSA密钥对密钥参数对象。
70    let rsaKeyPairSpec = genRsa2048KeyPairSpec();
71    // 构造RSA密钥对生成器。
72    let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec);
73    // sign和verfiy均支持RSA密钥带长度/不带长度的写法。
74    let signer = cryptoFramework.createSign("RSA|PSS|SHA256|MGF1_SHA256");
75    let verifyer = cryptoFramework.createVerify("RSA2048|PSS|SHA256|MGF1_SHA256");
76    let keyPair = await rsaGeneratorSpec.generateKeyPair();
77    await signer.init(keyPair.priKey);
78    // 在签名初始化后,对PSS参数进行set和get操作。
79    let setN = 32;
80    signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN);
81    let saltLen = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM);
82    console.info("SaltLen == " + saltLen);
83    let tf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM);
84    console.info("trailer field == " + tf);
85    let md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR);
86    console.info("md == " + md);
87    let mgf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR);
88    console.info("mgf == " + mgf);
89    let mgf1Md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR);
90    console.info("mgf1Md == " + mgf1Md);
91    await signer.update(input1);
92    let signMessageBlob = await signer.sign(input2);
93    // 在验签初始化前,对PSS参数进行set和get操作。
94    verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN);
95    saltLen = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM);
96    console.info("SaltLen == " + saltLen);
97    tf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM);
98    console.info("trailer field == " + tf);
99    md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR);
100    console.info("md == " + md);
101    mgf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR);
102    console.info("mgf == " + mgf);
103    mgf1Md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR);
104    await verifyer.init(keyPair.pubKey);
105    await verifyer.update(input1);
106    let verifyResult = await verifyer.verify(input2, signMessageBlob);
107    if (verifyResult === true) {
108      console.info('verify success');
109    } else {
110      console.error('verify failed');
111    }
112  }
113  ```
114
115- 同步方法示例:
116
117  ```ts
118  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
119  import { buffer } from '@kit.ArkTS';
120  // 根据密钥参数属性构造RSA非对称密钥对密钥参数。
121  function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) {
122    let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
123      n: nIn,
124      algName: "RSA",
125      specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
126    };
127    let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = {
128      params: rsaCommSpec,
129      sk: dIn,
130      pk: eIn,
131      algName: "RSA",
132      specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC
133    };
134    return rsaKeyPairSpec;
135  }
136  // 生成RSA2048密钥对参数。
137  function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec {
138    let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
139    let eIn = BigInt("0x010001");
140    let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1");
141    return genRsaKeyPairSpec(nIn, eIn, dIn);
142  }
143
144  function verifyMessagePSS() {
145    // 完整的明文被拆分为input1和input2。
146    let plan1 = "This is Sign test plan1";
147    let plan2 = "This is Sign test plan2";
148    let input1: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(plan1, 'utf-8').buffer) };
149    let input2: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(plan2, 'utf-8').buffer) };
150    // 获得RSA密钥对密钥参数对象。
151    let rsaKeyPairSpec = genRsa2048KeyPairSpec();
152    // 构造RSA密钥对生成器。
153    let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec);
154    // sign和verfiy均支持RSA密钥带长度/不带长度的写法。
155    let signer = cryptoFramework.createSign("RSA|PSS|SHA256|MGF1_SHA256");
156    let verifyer = cryptoFramework.createVerify("RSA2048|PSS|SHA256|MGF1_SHA256");
157    let keyPair = rsaGeneratorSpec.generateKeyPairSync();
158    signer.initSync(keyPair.priKey);
159    // 在签名初始化后,对PSS参数进行set和get操作。
160    let setN = 32;
161    signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN);
162    let saltLen = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM);
163    console.info("SaltLen == " + saltLen);
164    let tf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM);
165    console.info("trailer field == " + tf);
166    let md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR);
167    console.info("md == " + md);
168    let mgf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR);
169    console.info("mgf == " + mgf);
170    let mgf1Md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR);
171    console.info("mgf1Md == " + mgf1Md);
172    signer.updateSync(input1);
173    let signMessageBlob = signer.signSync(input2);
174    // 在验签初始化前,对PSS参数进行set和get操作。
175    verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN);
176    saltLen = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM);
177    console.info("SaltLen == " + saltLen);
178    tf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM);
179    console.info("trailer field == " + tf);
180    md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR);
181    console.info("md == " + md);
182    mgf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR);
183    console.info("mgf == " + mgf);
184    mgf1Md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR);
185    verifyer.initSync(keyPair.pubKey);
186    verifyer.updateSync(input1);
187    let verifyResult = verifyer.verifySync(input2, signMessageBlob);
188    if (verifyResult === true) {
189      console.info('verify success');
190    } else {
191      console.error('verify failed');
192    }
193  }
194  ```