@starbase/cryptic
Version:
Starbase Cryptography
2 lines (1 loc) • 5.45 kB
JavaScript
;function Cryptic(webCrypto,encoder,decoder){let crypto=webCrypto;"undefined"!=typeof window&&(crypto=window.crypto||webCrypto);let TextEncoder=encoder,TextDecoder=decoder;"undefined"!=typeof window&&(TextEncoder=window.TextEncoder,TextDecoder=window.TextDecoder);const toHex=byteArray=>Array.from(new Uint8Array(byteArray)).map(val=>("0"+val.toString(16)).slice(-2)).join("");const encode=byteArray=>btoa(Array.from(new Uint8Array(byteArray)).map(val=>String.fromCharCode(val)).join("")).replace(/\+/g,"-").replace(/\//g,"_").replace(/\=/g,""),decode=str=>new Uint8Array(atob(str.replace(/\_/g,"/").replace(/\-/g,"+")).split("").map(val=>val.charCodeAt(0))),fromText=string=>(new TextEncoder).encode(string),toText=byteArray=>(new TextDecoder).decode(byteArray);const random=size=>crypto.getRandomValues(new Uint8Array(size));var ecdsaSign=async(key,msg,curve="P-256",hashAlg="SHA-256")=>{var sig=msg.toString(),signKey=await crypto.subtle.importKey("pkcs8",decode(key),{name:"ECDSA",namedCurve:curve},!1,["sign"]),sig=await crypto.subtle.sign({name:"ECDSA",hash:hashAlg},signKey,fromText(sig));return encode(sig)},ecdsaVerify=async(pub,sig,msg,curve="P-256",hashAlg="SHA-256")=>{var message=msg.toString(),verifyKey=await crypto.subtle.importKey("spki",decode(pub),{name:"ECDSA",namedCurve:curve},!1,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:hashAlg},verifyKey,decode(sig),fromText(message))};const hmacSign=async(bits,msg,hashAlg="SHA-256")=>{var sig=msg.toString(),hmacKey=await crypto.subtle.importKey("raw",bits,{name:"HMAC",hash:hashAlg},!1,["sign"]),sig=await crypto.subtle.sign({name:"HMAC",hash:hashAlg},hmacKey,fromText(sig));return encode(sig)};const pbkdf2=async(bits,salt,iterations=1,size=256,hashAlg="SHA-256")=>{var result=await crypto.subtle.importKey("raw",bits,{name:"PBKDF2"},!1,["deriveBits"]),result=await crypto.subtle.deriveBits({name:"PBKDF2",salt:salt,iterations:iterations,hash:hashAlg},result,size);return encode(result)};const encrypt=async(plaintext,bits,AD=null)=>{var key=await crypto.subtle.importKey("raw",bits,{name:"AES-GCM"},!1,["encrypt"]),iv=random(12),cipher=fromText(plaintext),cipher=await crypto.subtle.encrypt({name:"AES-GCM",iv:iv,additionalData:AD||fromText("")},key,cipher);return encode(iv)+"."+encode(cipher)},decrypt=async(ciphertext="",bits,AD=null)=>{var key=await crypto.subtle.importKey("raw",bits,{name:"AES-GCM"},!1,["decrypt"]),iv=decode(ciphertext.split(".")[0]),decrypted=decode(ciphertext.split(".")[1]),decrypted=await crypto.subtle.decrypt({name:"AES-GCM",iv:iv,additionalData:AD||fromText("")},key,decrypted).catch(err=>{throw{message:"Failed to decrypt message.",error:err}});return toText(decrypted)};return{combine:(bitsA=[],bitsB=[])=>{let A=bitsA,B=bitsB;"string"==typeof bitsA&&(A=decode(bitsA)),"string"==typeof bitsB&&(B=decode(bitsB));var a=new Uint8Array(A),b=new Uint8Array(B);let c=new Uint8Array(a.length+b.length);return c.set(a),c.set(b,a.length),c},createECDH:async(curve="P-256")=>{var key=await crypto.subtle.generateKey({name:"ECDH",namedCurve:curve},!0,["deriveBits"]),pub=await crypto.subtle.exportKey("spki",key.publicKey),key=await crypto.subtle.exportKey("pkcs8",key.privateKey);return{pub:encode(pub),key:encode(key)}},createECDSA:async(curve="P-256")=>{var key=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:curve},!0,["sign","verify"]),pub=await crypto.subtle.exportKey("spki",key.publicKey),key=await crypto.subtle.exportKey("pkcs8",key.privateKey);return{pub:encode(pub),key:encode(key)}},decode:decode,encode:encode,decrypt:decrypt,digest:async(bits,hashAlg="SHA-256")=>{var result=await crypto.subtle.digest({name:hashAlg},bits);return toHex(result)},ecdh:async(key,pub,curve="P-256",size=256)=>{var pubKey=await crypto.subtle.importKey("spki",decode(pub),{name:"ECDH",namedCurve:curve},!0,[]),shared=await crypto.subtle.importKey("pkcs8",decode(key),{name:"ECDH",namedCurve:curve},!0,["deriveBits"]),shared=await crypto.subtle.deriveBits({name:"ECDH",public:pubKey},shared,size);return encode(shared)},ecdsaSign:ecdsaSign,ecdsaVerify:ecdsaVerify,encode:encode,encrypt:encrypt,fromHex:str=>{let result=new Uint8Array(str.match(/.{0,2}/g).map(val=>parseInt(val,16)));return result.slice(0,result.length-1)},fromText:fromText,hmacSign:hmacSign,hmacVerify:async(bits,sig,msg,hashAlg="SHA-256")=>{var message=msg.toString(),verifyKey=await crypto.subtle.importKey("raw",bits,{name:"HMAC",hash:hashAlg},!1,["verify"]);return await crypto.subtle.verify({name:"HMAC",hash:hashAlg},verifyKey,decode(sig),fromText(message))},kdf:async(bits,salt,info,size,hashAlg="SHA-256")=>{var key=await hmacSign(bits,toText(info));return await pbkdf2(decode(key),salt,1,size,hashAlg)},passwordDecrypt:async(ciphertext="",password="")=>{var encrypted=toText(decode(ciphertext.split(".")[0])),keyBits=ciphertext.split(".")[1],keyBits=await pbkdf2(fromText(password),decode(keyBits),encrypted,256),encrypted=ciphertext.split(".").slice(2).join(".");return await decrypt(encrypted,decode(keyBits))},passwordEncrypt:async(message,password="",iterations=1e5)=>{var salt=random(32),encrypted=await pbkdf2(fromText(password),salt,iterations,256),encrypted=await encrypt(message,decode(encrypted));return encode(fromText(iterations.toString()))+"."+encode(salt)+"."+encrypted},pbkdf2:pbkdf2,random:random,sign:ecdsaSign,toHex:toHex,toText:toText,verify:ecdsaVerify}}"undefined"!=typeof module&&module&&module.exports&&(module.exports=Cryptic);