import * as base64js from 'base64-js' ; if ( typeof process === 'undefined' && typeof TextEncoder === 'undefined' ) { require ( 'fast-text-encoding' ) ; } import { Crypto , JwkCertificate , fromArrayBufferToHex } from '../crypto' ; export class BrowserCrypto implements Crypto { constructor ( ) { if ( typeof window === 'undefined' || window . crypto === undefined || window . crypto . subtle === undefined ) { throw new Error ( "SubtleCrypto not found. Make sure it's an https:// website." ) ; } } async sha256DigestBase64 ( str ) { const inputBuffer = new TextEncoder ( ) . encode ( str ) ; const outputBuffer = await window . crypto . subtle . digest ( 'SHA-256' , inputBuffer ) ; return base64js . fromByteArray ( new Uint8Array ( outputBuffer ) ) ; } randomBytesBase64 ( count ) { const array = new Uint8Array ( count ) ; window . crypto . getRandomValues ( array ) ; return base64js . fromByteArray ( array ) ; } private static padBase64 ( base64 ) { while ( base64 . length % 4 !== 0 ) { base64 += '=' ; } return base64 ; } async verify ( pubkey , data , signature ) { const algo = { name : 'RSASSA-PKCS1-v1_5' , hash : { name : 'SHA-256' } , } ; const dataArray = new TextEncoder ( ) . encode ( data ) ; const signatureArray = base64js . toByteArray ( BrowserCrypto . padBase64 ( signature ) ) ; const cryptoKey = await window . crypto . subtle . importKey ( 'jwk' , pubkey , algo , true , [ 'verify' ] ) ; const result = await window . crypto . subtle . verify ( algo , cryptoKey , signatureArray , dataArray ) ; return result ; } async sign ( privateKey , data ) { const algo = { name : 'RSASSA-PKCS1-v1_5' , hash : { name : 'SHA-256' } , } ; const dataArray = new TextEncoder ( ) . encode ( data ) ; const cryptoKey = await window . crypto . subtle . importKey ( 'jwk' , privateKey , algo , true , [ 'sign' ] ) ; const result = await window . crypto . subtle . sign ( algo , cryptoKey , dataArray ) ; return base64js . fromByteArray ( new Uint8Array ( result ) ) ; } decodeBase64StringUtf8 ( base64 ) { const uint8array = base64js . toByteArray ( BrowserCrypto . padBase64 ( base64 ) ) ; const result = new TextDecoder ( ) . decode ( uint8array ) ; return result ; } encodeBase64StringUtf8 ( text ) { const uint8array = new TextEncoder ( ) . encode ( text ) ; const result = base64js . fromByteArray ( uint8array ) ; return result ; } param str return async sha256DigestHex ( str ) { const inputBuffer = new TextEncoder ( ) . encode ( str ) ; const outputBuffer = await window . crypto . subtle . digest ( 'SHA-256' , inputBuffer ) ; return fromArrayBufferToHex ( outputBuffer ) ; } param key param msg return async signWithHmacSha256 ( key , msg ) { const rawKey = typeof key === 'string' ? key : String . fromCharCode ( ... new Uint16Array ( key ) ) ; const enc = new TextEncoder ( ) ; const cryptoKey = await window . crypto . subtle . importKey ( 'raw' , enc . encode ( rawKey ) , { name : 'HMAC' , hash : { name : 'SHA-256' , } , } , false , [ 'sign' ] ) ; return window . crypto . subtle . sign ( 'HMAC' , cryptoKey , enc . encode ( msg ) ) ; } }