使用危险品库加载原始 Public EC 密钥
Load Raw Public EC Key using hazmat library
我使用 JS 生成了以下私钥和 public 密钥:
priv: auLHORUBmv5n48jUDA1TskAmJWFi4TFEmjE1GjgjEB8
pub : BFvn-Qk8HWPwgI5ZgCiWxJV5SYdTXbkVz66sgoEslLxotftRGLEOeIPXVcnQD95eETqW9zM7ejB1MqCc0tvR-0g
要生成的代码 (JavaScript):
const pair = generateKeyPairSync('ec', { namedCurve: 'prime256v1' })
const privateKeyDer = pair.privateKey.export({ format: 'der', type: 'pkcs8' })
const privateRaw = privateKeyDer.slice(36, 68)
const publicRaw = privateKeyDer.slice(73)
console.log(`priv: ${webSafe64(privateRaw)}`)
console.log(`pub : ${webSafe64(publicRaw)}`)
现在,我有 Python 个项目需要使用 cryptography.hazmat.primitives.serialization.load_der_public_key()
加载 public 密钥
load_der_public_key(base64.b64decode(publicRaw))
我似乎不知道该怎么做。不断出现错误:
Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm.
尝试将该字符串转换为字节,并将 base64 转换为字节,但没有成功。
您混淆了两种格式,一种是 raw public 密钥,另一种是 中 DER 编码的 public 密钥X.509/SPKI 格式。
发布的public键:
BFvn-Qk8HWPwgI5ZgCiWxJV5SYdTXbkVz66sgoEslLxotftRGLEOeIPXVcnQD95eETqW9zM7ejB1MqCc0tvR-0g
是 Base64url 编码的原始 public 密钥。十六进制编码,格式为 0x04 + x + y,secp256r1(又名 prime256v1)的大小为 65 字节:
045be7f9093c1d63f0808e59802896c495794987535db915cfaeac82812c94bc68b5fb5118b10e7883d755c9d00fde5e113a96f7333b7a307532a09cd2dbd1fb48
在 Python 中,可以使用 Cryptography 库的 from_encoded_point()
导入原始 public 密钥,例如:
from cryptography.hazmat.primitives.asymmetric import ec
import base64
curve = ec.SECP256R1()
publicKeyRaw = base64.urlsafe_b64decode('BFvn-Qk8HWPwgI5ZgCiWxJV5SYdTXbkVz66sgoEslLxotftRGLEOeIPXVcnQD95eETqW9zM7ejB1MqCc0tvR-0g=');
publicKey = ec.EllipticCurvePublicKey.from_encoded_point(curve, publicKeyRaw);
然而,对于使用 load_der_public_key()
的导入,密钥必须以 X.509/SPKI 格式导出,并在 NodeJS 代码中进行 DER 编码。这可以实现,例如与
var publicKeyDer = pair.publicKey.export({ format: 'der', type: 'spki' })
当然,也可以在两种格式之间进行转换。但是由于 Cryptography 库支持两种格式的导入,所以实际上没有必要。
我使用 JS 生成了以下私钥和 public 密钥:
priv: auLHORUBmv5n48jUDA1TskAmJWFi4TFEmjE1GjgjEB8
pub : BFvn-Qk8HWPwgI5ZgCiWxJV5SYdTXbkVz66sgoEslLxotftRGLEOeIPXVcnQD95eETqW9zM7ejB1MqCc0tvR-0g
要生成的代码 (JavaScript):
const pair = generateKeyPairSync('ec', { namedCurve: 'prime256v1' })
const privateKeyDer = pair.privateKey.export({ format: 'der', type: 'pkcs8' })
const privateRaw = privateKeyDer.slice(36, 68)
const publicRaw = privateKeyDer.slice(73)
console.log(`priv: ${webSafe64(privateRaw)}`)
console.log(`pub : ${webSafe64(publicRaw)}`)
现在,我有 Python 个项目需要使用 cryptography.hazmat.primitives.serialization.load_der_public_key()
load_der_public_key(base64.b64decode(publicRaw))
我似乎不知道该怎么做。不断出现错误:
Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm.
尝试将该字符串转换为字节,并将 base64 转换为字节,但没有成功。
您混淆了两种格式,一种是 raw public 密钥,另一种是 中 DER 编码的 public 密钥X.509/SPKI 格式。
发布的public键:
BFvn-Qk8HWPwgI5ZgCiWxJV5SYdTXbkVz66sgoEslLxotftRGLEOeIPXVcnQD95eETqW9zM7ejB1MqCc0tvR-0g
是 Base64url 编码的原始 public 密钥。十六进制编码,格式为 0x04 + x + y,secp256r1(又名 prime256v1)的大小为 65 字节:
045be7f9093c1d63f0808e59802896c495794987535db915cfaeac82812c94bc68b5fb5118b10e7883d755c9d00fde5e113a96f7333b7a307532a09cd2dbd1fb48
在 Python 中,可以使用 Cryptography 库的 from_encoded_point()
导入原始 public 密钥,例如:
from cryptography.hazmat.primitives.asymmetric import ec
import base64
curve = ec.SECP256R1()
publicKeyRaw = base64.urlsafe_b64decode('BFvn-Qk8HWPwgI5ZgCiWxJV5SYdTXbkVz66sgoEslLxotftRGLEOeIPXVcnQD95eETqW9zM7ejB1MqCc0tvR-0g=');
publicKey = ec.EllipticCurvePublicKey.from_encoded_point(curve, publicKeyRaw);
然而,对于使用 load_der_public_key()
的导入,密钥必须以 X.509/SPKI 格式导出,并在 NodeJS 代码中进行 DER 编码。这可以实现,例如与
var publicKeyDer = pair.publicKey.export({ format: 'der', type: 'spki' })
当然,也可以在两种格式之间进行转换。但是由于 Cryptography 库支持两种格式的导入,所以实际上没有必要。