function stringToArrayBuffer(str: string): ArrayBuffer {
const encoder = new TextEncoder();
const uint8Array = encoder.encode(str);
return uint8Array.buffer;
}
* sting字符串转ArrayBuffer
* @param str
* @returns
*/
function strToArrayBuffer(str: string): ArrayBuffer {
const buffer = new ArrayBuffer(str.length);
const viewArray = new Uint8Array(buffer);
let i = 0;
while (i < str.length) {
viewArray[i] = str.charCodeAt(i);
i++;
}
return buffer;
}
* 通过pem格式的公钥/私钥生成CryptoKey对象
* @param pem pem字符串
* @param [hash] hash算法,默认SHA-512。注意安全要求不可使用SHA-1
* @param [isPublicKey] 是否为公钥
* @returns CryptoKey对象
*/
async function importRsaKey(pem: any, hash = 'SHA-512', isPublicKey = true): Promise<CryptoKey> {
const headerStr = `-----BEGIN ${isPublicKey ? `PUBLIC` : `PRIVATE`} KEY-----`;
const footerStr = `-----END ${isPublicKey ? `PUBLIC` : `PRIVATE`} KEY-----`;
const headerLen = headerStr.length;
let footerLen = footerStr.length;
if (pem[pem.length - footerStr.length] === '\n') {
footerLen++;
}
if (pem[pem.length - 1] === '\n') {
footerLen++;
}
const base64Contents = pem.substring(headerLen, pem.length - footerLen);
const pemStr = window.atob(base64Contents);
const pemBuffer = strToArrayBuffer(pemStr);
return await window.crypto.subtle.importKey(
isPublicKey ? 'spki' : 'pkcs8',
pemBuffer,
{
name: 'RSA-OAEP',
hash
},
true,
[isPublicKey ? 'encrypt' : 'decrypt']
);
}
* 通过pem格式的公钥生成CryptoKey对象
* @param pem pem公钥字符串
* @param [hash] hash算法,默认SHA-512。注意安全要求不可使用SHA-1
* @returns CryptoKey对象
*/
export async function importRsaPublicKey(pem: string, hash = 'SHA-1'): Promise<CryptoKey> {
return await importRsaKey(pem, hash, true);
}
* Rsas encrypt
* @param srcStr 待加密的字符串
* @param publicKey 公钥,需要先使用importRsaPublicKey函数导入生成公钥对象
* @returns encrypt
*/
export async function rsaEncrypt(srcStr: string, publicKey: CryptoKey): Promise<string> {
const encodedStr = stringToArrayBuffer(srcStr);
return await crypto.subtle.encrypt(
{
name: 'RSA-OAEP'
},
publicKey,
encodedStr
);
}
export async function rsaDecrypt(srcStr: ArrayBuffer, privateKey: CryptoKey): Promise<string> {
return await crypto.subtle.decrypt(
{
name: 'RSA-OAEP'
},
privateKey,
srcStr
);
}
* ArrayBuffer转string字符串
* @returns
* @param arrayBuffer
*/
export function arrayBufferToHexStr(arrayBuffer: any): string {
if (
typeof arrayBuffer !== 'object' ||
arrayBuffer === null ||
typeof arrayBuffer.byteLength !== 'number'
) {
throw new TypeError('Expected input to be an ArrayBuffer');
}
const view = new Uint8Array(arrayBuffer);
let result = '';
let value;
view.forEach(e => {
value = e.toString(16);
result += value.length === 1 ? `0${value}` : value;
});
return result;
}