问题的解决方案是,在使用Python cryptography库和JS Forge库进行pkcs #7签名时,需要注意两个库在编码方式上的差异。具体来说,Python cryptography库默认使用DER编码格式,而JS Forge库默认使用PEM编码格式。因此,在数据传输和处理过程中,需要将数据在两种编码格式之间进行相互转换。
以下是Python cryptography库中进行pkcs #7签名的示例代码:
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding, utils
def pkcs7_sign(private_key, cert, data):
builder = cert.signature_builder(padding.PKCS1v15(), hashes.SHA256())
signature = private_key.sign(data, padding.PKCS1v15(), hashes.SHA256())
signed = builder.build(signature)
return signed
# Usage:
# private_key and cert should be loaded from file
data = b'test data'
signed_data = pkcs7_sign(private_key, cert, data)
以下是JS Forge库中进行pkcs #7签名的示例代码:
const forge = require('node-forge');
function pkcs7_sign(privateKeyPem, certPem, data) {
const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
const cert = forge.pki.certificateFromPem(certPem);
const p7 = forge.pkcs7.createSignedData();
p7.content = forge.util.createBuffer(data);
p7.addCertificate(cert);
p7.addSigner({
key: privateKey,
certificate: cert,
digestAlgorithm: forge.pki.oids.sha256,
authenticatedAttributes: [{
type: forge.pki.oids.contentType,
value: forge.pki.oids.data,
}, {
type: forge.pki.oids.messageDigest,
value: forge.util.encode64(forge.md.sha256.create().update(data).digest().getBytes()),
}, {
type: forge.pki.oids.signingTime,
value: new Date(),
}],
});
p7.sign();
return forge.asn1.toDer(p7.toAsn1()).getBytes();
}
// Usage:
// privateKeyPem and certPem should be loaded from file
const data = 'test data';
const signedData = pkcs7_sign(privateKeyPem, certPem, data);
在两种编码格式之间进行转换,可以使用以下代码:
from cryptography.hazmat.primitives import serialization
def der_to_pem(der_data):
pem_data = serialization.load_der_public_key(der_data).public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
return pem_data
def pem_to_der(pem_data):
der_data = serialization.load_pem_public_key(pem_data).public_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
return der_data
const forge = require('node-forge');
function derToPem(derData) {
const pemData = forge.pki.publicKeyToPem(forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(derData)));
return pemData;
}
function pemToDer(pemData) {
const derData = forge.asn1.toDer(forge.pki.publicKeyToAsn1(forge.pki.publicKeyFromPem(pemData))).getBytes();
return derData;
}