const crypto = require('crypto');
// Generate a key pair for this example
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
});
// Message to sign and verify
const message = 'Message to verify with different options';
// Function to sign with specific options
function signWithOptions(algorithm, message, privateKey, options = {}) {
const sign = crypto.createSign(algorithm);
sign.update(message);
const keyWithOptions = {
key: privateKey,
...options
};
return sign.sign(keyWithOptions, 'hex');
}
// Function to verify with specific options
function verifyWithOptions(algorithm, message, publicKey, signature, options = {}) {
const verify = crypto.createVerify(algorithm);
verify.update(message);
const keyWithOptions = {
key: publicKey,
...options
};
return verify.verify(keyWithOptions, signature, 'hex');
}
// 1. Standard PKCS#1 v1.5 padding (default)
console.log('1. Standard PKCS#1 v1.5 padding:');
const sig1 = signWithOptions('SHA256', message, privateKey);
console.log('Signature:', sig1.substring(0, 32) + '...');
console.log('Verification result:', verifyWithOptions('SHA256', message, publicKey, sig1));
// 2. PSS padding
console.log('\n2. PSS padding:');
const sig2 = signWithOptions('SHA256', message, privateKey, {
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: 32
});
console.log('Signature:', sig2.substring(0, 32) + '...');
console.log('Verification result:', verifyWithOptions('SHA256', message, publicKey, sig2, {
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: 32
}));
// 3. Different salt lengths with PSS padding
console.log('\n3. PSS padding with different salt lengths:');
[16, 32, 64].forEach(saltLength => {
try {
const sig = signWithOptions('SHA256', message, privateKey, {
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength
});
const isValid = verifyWithOptions('SHA256', message, publicKey, sig, {
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength
});
console.log(`Salt length ${saltLength}: ${isValid ? 'Verified' : 'Failed'}`);
} catch (error) {
console.log(`Salt length ${saltLength}: Error - ${error.message}`);
}
});
// 4. Mismatched padding (should fail)
console.log('\n4. Mismatched padding (should fail):');
try {
const sig3 = signWithOptions('SHA256', message, privateKey, {
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: 32
});
// Try to verify with wrong padding
const isValid = verifyWithOptions('SHA256', message, publicKey, sig3, {
// No padding specified - should use default (PKCS#1 v1.5)
});
console.log('Verification with mismatched padding:', isValid);
} catch (error) {
console.log('Error:', error.message);
}
// 5. Using dsaEncoding option (for DSA keys)
console.log('\n5. DSA with specific encoding:');
try {
// Generate DSA key pair
const { privateKey: dsaPrivateKey, publicKey: dsaPublicKey } = crypto.generateKeyPairSync('dsa', {
modulusLength: 2048,
divisorLength: 256,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
});
// Sign with DSA
const signDSA = crypto.createSign('SHA256');
signDSA.update(message);
const dsaSignature = signDSA.sign({
key: dsaPrivateKey,
dsaEncoding: 'ieee-p1363' // or 'der' (default)
}, 'hex');
// Verify with DSA
const verifyDSA = crypto.createVerify('SHA256');
verifyDSA.update(message);
const isDSAValid = verifyDSA.verify({
key: dsaPublicKey,
dsaEncoding: 'ieee-p1363' // must match signing encoding
}, dsaSignature, 'hex');
console.log('DSA signature verification:', isDSAValid);
} catch (error) {
console.log('DSA verification error:', error.message);
}