Home > Mobile >  nodejs webcrypto imporKey rsa error "error:0D07207B:asn1 encoding routines:ASN1_get_object:head
nodejs webcrypto imporKey rsa error "error:0D07207B:asn1 encoding routines:ASN1_get_object:head

Time:10-07

Ok, so I was building an application and using RSA to decrypt data encrypted from the browser's webcrypto and I was getting a strange error before the web side even started.. I tried searching the error but I didn't find anything helpful.. I'm using nodejs(v16.10.0)

//failing nodejs example
var crypto=require('crypto')
var privateKeyStr=`-----BEGIN PRIVATE KEY-----
REAL_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----`
function str2ab(str) {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i  ) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}
function ab2str(buf,getOwnPropertyNames) {
    var buff=new Uint8Array(buf)
    return Object.getOwnPropertyNames(buff)
    .map(i=>String.fromCharCode(buff[i])).join('')
}

atob=(text)=>Buffer.from(text,'base64').toString()
btoa=(text)=>Buffer.from(text).toString('base64')

let pemHead1="-----BEGIN PRIVATE KEY-----", pemFoot1="-----END PRIVATE KEY-----"

var prvKeyText=atob(privateKeyStr.substring(pemHead1.length,privateKeyStr.length-pemFoot1.length));

(async()=>{
  prvKey=await crypto.webcrypto.subtle.importKey('pkcs8',str2ab(prvKeyText),{name:"RSA-OAEP",hash:"SHA-256"},true,['decrypt'])
  
  rsa_decrypt=async(secret_text)=>ab2str( await crypto.webcrypto.subtle.decrypt('RSA-OAEP',prvKey,str2ab(atob(secret_text))) )
})()

And this kind of code for webcrypto does work in the browser but it fails in nodejs(v16.10.0)

//working web example(yes this is not a private key I'm using)
var privateKeyStr=`-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDUXCf0zdHCtVGY
kGAP0cSHZcdt5R A0wiYNYmGa4Q4TmyZxI8w2HjrbREwH51c/rJ7KxEwPmx288zX
yESmswSDENS/mb 5Kvo oHZCLFHzL z VoCBLDUGCMDMEs1nyEDjsXlLXkuceR6Y
n/YSjy/jSA8ens/Q883PseXPetJBtKxmixVS9DKGuLgYuz22XwaKEOB5SD5WIa0f
Rj8WkS5NU 7GBoAFPtCTNcq1D3qKhb4ifoQIeUfKz8ITrNSQ8hUYrkNSOirJj9tk
K4pb/QHu/pKqL7eoFlNiwbP0FhoWdmSPTbU4xYpSAyjT/qT dGOXEIZxI623tDO3
ZNVDPcF9Sm6rGqrsWbUfkBK413ZX6I98g2aktsHsHaNNLrRU6l p0T0l89 bNDt7
r/vgWV0FWbzyXHbZBhDhLj6eWL8lLAPQlYtgkpsZNZkZRT3wdzeRAAm7WVKeODW9
e5wg5WJpJ EkbBZBaLqtXi4P84eNieg2q4nhyiC  XyokfNtKreideKnRqp9R84h
O19iu 2MEeiy1mJvqqIwa0bhsSHzr6aO4HBgWDn5ierdLQo2EuFNDblGlao98h26
3BJO5bBurVAczbdYJvT8rLCUEwYsDwAnXMeXs3ezv4hualp3VeExgyiYoPZUIPZS
eh8zbk6Gnaz8mmSkRPyKl4gbDzS5 QIDAQABAoICAA2OtJ5UZYfgu4zZ6sgXxExA
mzLQ5en7jxjokhca1h4iI5zNh7a mzmshORloE5HlG14mmhSE qkNfewuXFLDIax
lGOHFU5lCATniaU/3xt/e8nhC MzR09TT7u3l5WAm2Pt KhvJLSgputnivY0XgJM
n2p9CRd1 TXBTcKpPLMlLbx NKZPIMqpEFfD3HTALFK0MSCNFC27iKnueiierC4T
pbLOx22OTRKY5JAapOAjGbhqC1PfKk4wZVuMNSXrzpz8wx ExyaHIKKMhRDKXk07
w3FKCpeYlUpAw5RZtOCqPlFHzMILGoGR4hFmuHHmTFVgoLSoanbH8mVK8rKQRsHz
KdQ8tLquQpnXf P Vx4hAP9cyjpfJWwQDtv3jq /bJiyrM50wJhYekimLEGfSQ0n
8k5vza1Q27/Rz1lG4A3YGew4ywbpsluY3QfT5tUVN ixtiNC15pbIE4LfUd0MN17
8MeQqHwiRVGBZzvGBebssuVw96kUOhZBGZ7DqjpaJU5WDBhXInkFTQNyPrwp d2K
FhwpAwWgPC7b8AIZPSj14aBr60ZDPv CM2Uug9Yc26ZRP emQVEGl6S1dEPDX/hV
Oe2tkjYtkqzwm1XwB5t0Dsvo60i4A5 NBYXzb8g hSqB9Cbr4uhkVGV1DZdk67bj
 5OX  wlMLyt04QtIwmBAoIBAQDzkUhryv4Ue/uCz5tXuY/qyUV1tOJFaGYBdVnQ
FIv6mOIHexMlAiSQnd0h CxTu8kx3 rqL3P6p97ErxYQ2YjmhczR0E4CBemLzxzV
CPLAJnKG I5fjSS QIDezSdn5hOZs0fhsGkfQmZ3x0WaYQDwiny5Hzfe4Ddoi4Ta
/Fms1h6rlB7gHY842GqskYgp6LjNoYEwAVMEVag3RwE2KIq034L6OywD  LhWOVi
itcWLUlyUzsrBxqgIfSkUFXK6GU8uqOwaZ2GIfn5/smRwaXj1WyJjG1zZT6wZ/Bl
Ku tSImKPYrvctp61Ob7IhwdliNOvvXR7xXTeftZeZVenLrlAoIBAQDfMxTx3/fg
jk4E1b8jCN4CuPoA3tflXrY70TEkNpaiqWdnhkmI7U3yQv70gYNYrbCXf6L5H w7
UH5mrLZmpyhBGeVAGweB0gw5K1nfZtuxYIsKBpefh/iTP5EPokBgGN3TysVyaPph
2uvvKsG0lN6sWDYKFtY5YDG2JoBkq9Ek0NfGu0v/GOmqvGXWn/CNu v9FGUZdUOb
6LuXbxwe/yY5Re02Qcwo2JjJrWqz60OIlnNmJ1XuP9EXsakGv/DOMYnbJylb9txq
cHh2eJxJneLyP8eRsIp6DhQaExgmHqmJbYTIipJXVi5QqtsCeSXYm0ZygtsASjqs
cFWSPGlCgg2FAoIBAQCuCDHR63IOWuRD/GkHjmwZm4SI7Rz78PNpuVraBcRa42Al
bjgoqlZMCrAVdIjfr367pz3n5M4e3FGdAWln0rcx14qYpBkI8waDwhHc2g7xYsdU
T0cTWPtXASnTiIzOfSOmH aNiQojrsMedID0JLmSJbGmaHr4Qgb1KTNdcQ/2Iew6
NpS1GAnc2S2nbjj3kPRy4SI4lcmmgDm4fYCNHPy27jlc6Giz1Aexcl48Qe4bR3KC
QJw3S1Un8/skaM5UNCcZ9FW/WEeYrrA5g2atQctxdm6d/Xu7By16yFmJP9uPWhQE
daLPIqafO35rFF04eq1xt5pXTViwCSmiLfCfcKdNAoIBACFhGUvG6 IYRhCxCqGp
rNIJadIBgZYa4PP3J/s7crGm1gEEczDYFGUbodddGxCDATrW6r JB6IjOpQOVkTp
0LpTrhY1NJ00lYFjO1COqGJRhtmb/Mbt5b3XrtEAudHlRh9rXrXqfy9tNwWQhmGE
NfzeQE6n9aek/Co6fc8QZvmzheGBly7yQde3zx8W0jnQFc3GZAw3nkHNv2g5RKJa
FBRSodQQaQDey5K1rZR0pafioCVx0ocL4jBB8H5C7DdZ7zzoEWZgd7wvT8Sf6veT
diI2aZkfJsZ0Hot7uYvR4BbeWxJGrvYCvHBx7Mjk50UKi7GKYkgb0cSCFDoHcNJy
cqUCggEAGJ 31rAPfxH7FXneYlMY9r2KlzAEWFSVFulDJpQNWEhqCQ1XvgqnVoCv
ymjZ8MqwpfAiu4Tiu9/mWY7qKLSxAJscu3qRpDDAU9qLQV67zHp/7/b5X7 j7Hjb
kg2 8sn/ZfIJLHhLueBniNU41xc2IEe/o52bd17juhj5BYFjiv7on83xcCKiGVxm
Em3IXian5uXHg58lb95XNs8rbpjbcNFC7CGtPFfd/sKH16ciButT6C14lXrEL3vH
i8L9n lbKM3UZDFmLO113GSCP adCmXiqSs6DgTiL71KrbNgtbNp4UvskxCq5xRf
PotgmE7pY/5T04uDwhpWK5TOFnCnXg==
-----END PRIVATE KEY-----`
function str2ab(str) {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i  ) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}
function ab2str(buf,getOwnPropertyNames) {
    var buff=new Uint8Array(buf)
    return Object.getOwnPropertyNames(buff)
    .map(i=>String.fromCharCode(buff[i])).join('')
}

let pemHead1="-----BEGIN PRIVATE KEY-----", pemFoot1="-----END PRIVATE KEY-----"

var prvKeyText=atob(privateKeyStr.substring(pemHead1.length,privateKeyStr.length-pemFoot1.length));

(async()=>{
  prvKey=await crypto.subtle.importKey('pkcs8',str2ab(prvKeyText),{name:"RSA-OAEP",hash:"SHA-256"},true,['decrypt'])
  
  console.log("it works normally")
  console.log(prvKey) //so clearly I don't understand webcrypto in nodejs v16.10.0
  
  rsa_decrypt=async(secret_text)=>ab2str( await crypto.subtle.decrypt('RSA-OAEP',prvKey,str2ab(atob(secret_text))) )
})()
//if an error happened you would see it.. but in your browser it works normal

CodePudding user response:

This is due to your atob() and btoa() methods defined for NodeJS.

Buffer.from() and Buffer#toString() apply UTF-8 by default if no other encoding is specified. However, UTF-8 generally corrupts arbitrary binary data. Instead of UTF-8 use binary as encoding:

atob = (text) => Buffer.from(text, 'base64').toString('binary')
btoa = (text) => Buffer.from(text, 'binary').toString('base64')

With this fix the import works and the error message is no longer displayed.

  • Related