将完成BASE64编码后的Header字符串与Payload字符串,通过“.”进行连接,并在开发者的应用中,通过服务账号密钥文件中的private_key(华为不进行存储,请您妥善保管),使用SHA256withRSA/PSS算法对拼接的字符串签名,最后将Header,Payload以及字符串签名通过“.”进行连接,即可得到Token数据。
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';
let base64 = new util.Base64Helper();
// 生成header
function genHeader(keyId: string): string {
const jwtHeader: object = new Object({
'kid': keyId,
'typ': 'JWT',
'alg': 'PS256'
});
let strArray = new Uint8Array(buffer.from(JSON.stringify(jwtHeader)).buffer);
return base64.encodeToStringSync(strArray, util.Type.BASIC_URL_SAFE);
}
// 生成payload
function genPayload(subAccount: string): string {
const now: number = Date.now();
const jwtPayload: object = new Object({
'aud': '*****',
'iss': subAccount,
'iat': now,
'exp': now + 3600 * 1000,
});
let strArray = new Uint8Array(buffer.from(JSON.stringify(jwtPayload)).buffer);
return base64.encodeToStringSync(strArray, util.Type.BASIC_URL_SAFE);
}
async function pss(priKey: string, str: string) {
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA2048');
let keyPair = asyKeyGenerator.convertPemKeySync(null, priKey);
let signer = cryptoFramework.createSign('RSA2048|PSS|SHA256|MGF1_SHA256');
await signer.init(keyPair.priKey);
signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, 32);
let signData = await signer.sign({ data: new Uint8Array(buffer.from(str).buffer) });
return signData.data;
}
export async function main() {
// 服务账号密钥,需要根据教程使用自己的密钥
const privateJson: object = new Object({
'project_id': '*****',
'key_id': '*****',
'private_key': '*****',
'sub_account': '*****',
'auth_uri': '*****',
'token_uri': '*****',
'auth_provider_cert_uri': '*****',
'client_cert_uri': '*****'
});
let header = genHeader(privateJson['key_id']);
let payload = genPayload(privateJson['sub_account']);
let hap = header + '.' + payload;
let signature = await pss(privateJson['private_key'], hap);
let token = hap + '.' + base64.encodeToStringSync(signature, util.Type.BASIC_URL_SAFE);
console.info(token);
}
@Entry
@Component
struct Index {
build() {
RelativeContainer() {
Text('HelloWorld')
.fontSize($r('app.float.page_text_font_size'))
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
main();
});
}
.height('100%')
.width('100%');
}
}
鉴权json字段是固定的,无法更改,取用也是需要用json格式。