crypto: allow padding in RSA methods
Reviewed-By: Trevor Norris <trevnorris@gmail.com>
This commit is contained in:
Родитель
8a7d7f8b2b
Коммит
6adf3ecebb
|
@ -597,17 +597,36 @@ Exports the encoded challenge associated with the SPKAC.
|
|||
|
||||
Encrypts `buffer` with `public_key`. Only RSA is currently supported.
|
||||
|
||||
`public_key` can be an object or a string. If `public_key` is a string, it is
|
||||
treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`.
|
||||
|
||||
`public_key`:
|
||||
|
||||
* `key` : A string holding the PEM encoded private key
|
||||
* `padding` : An optional padding value, one of the following:
|
||||
* `constants.RSA_NO_PADDING`
|
||||
* `constants.RSA_PKCS1_PADDING`
|
||||
* `constants.RSA_PKCS1_OAEP_PADDING`
|
||||
|
||||
NOTE: All paddings are defined in `constants` module.
|
||||
|
||||
## crypto.privateDecrypt(private_key, buffer)
|
||||
|
||||
Decrypts `buffer` with `private_key`.
|
||||
|
||||
`private_key` can be an object or a string. If `private_key` is a string, it is
|
||||
treated as the key with no passphrase.
|
||||
treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`.
|
||||
|
||||
`private_key`:
|
||||
|
||||
* `key` : A string holding the PEM encoded private key
|
||||
* `passphrase` : A string of passphrase for the private key
|
||||
* `passphrase` : An optional string of passphrase for the private key
|
||||
* `padding` : An optional padding value, one of the following:
|
||||
* `constants.RSA_NO_PADDING`
|
||||
* `constants.RSA_PKCS1_PADDING`
|
||||
* `constants.RSA_PKCS1_OAEP_PADDING`
|
||||
|
||||
NOTE: All paddings are defined in `constants` module.
|
||||
|
||||
## crypto.DEFAULT_ENCODING
|
||||
|
||||
|
|
|
@ -355,14 +355,17 @@ Verify.prototype.verify = function(object, signature, sigEncoding) {
|
|||
return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding));
|
||||
};
|
||||
|
||||
exports.publicEncrypt = function(object, buffer) {
|
||||
return binding.publicEncrypt(toBuf(object), buffer);
|
||||
exports.publicEncrypt = function(options, buffer) {
|
||||
var key = options.key || options;
|
||||
var padding = options.padding || constants.RSA_PKCS1_OAEP_PADDING;
|
||||
return binding.publicEncrypt(toBuf(key), buffer, padding);
|
||||
};
|
||||
|
||||
exports.privateDecrypt = function(options, buffer) {
|
||||
var key = options.key || options;
|
||||
var passphrase = options.passphrase || null;
|
||||
return binding.privateDecrypt(toBuf(key), buffer, passphrase);
|
||||
var padding = options.padding || constants.RSA_PKCS1_OAEP_PADDING;
|
||||
return binding.privateDecrypt(toBuf(key), buffer, padding, passphrase);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -950,6 +950,30 @@ void DefineOpenSSLConstants(Handle<Object> target) {
|
|||
#define NPN_ENABLED 1
|
||||
NODE_DEFINE_CONSTANT(target, NPN_ENABLED);
|
||||
#endif
|
||||
|
||||
#ifdef RSA_PKCS1_PADDING
|
||||
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PADDING);
|
||||
#endif
|
||||
|
||||
#ifdef RSA_SSLV23_PADDING
|
||||
NODE_DEFINE_CONSTANT(target, RSA_SSLV23_PADDING);
|
||||
#endif
|
||||
|
||||
#ifdef RSA_NO_PADDING
|
||||
NODE_DEFINE_CONSTANT(target, RSA_NO_PADDING);
|
||||
#endif
|
||||
|
||||
#ifdef RSA_PKCS1_OAEP_PADDING
|
||||
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_OAEP_PADDING);
|
||||
#endif
|
||||
|
||||
#ifdef RSA_X931_PADDING
|
||||
NODE_DEFINE_CONSTANT(target, RSA_X931_PADDING);
|
||||
#endif
|
||||
|
||||
#ifdef RSA_PKCS1_PSS_PADDING
|
||||
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DefineSystemConstants(Handle<Object> target) {
|
||||
|
|
|
@ -3552,6 +3552,7 @@ template <PublicKeyCipher::Operation operation,
|
|||
bool PublicKeyCipher::Cipher(const char* key_pem,
|
||||
int key_pem_len,
|
||||
const char* passphrase,
|
||||
int padding,
|
||||
const unsigned char* data,
|
||||
int len,
|
||||
unsigned char** out,
|
||||
|
@ -3610,8 +3611,9 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
|
|||
goto exit;
|
||||
if (EVP_PKEY_cipher_init(ctx) <= 0)
|
||||
goto exit;
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0)
|
||||
goto exit;
|
||||
|
||||
if (EVP_PKEY_cipher(ctx, NULL, out_len, data, len) <= 0)
|
||||
goto exit;
|
||||
|
||||
|
@ -3649,7 +3651,9 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
|||
char* buf = Buffer::Data(args[1]);
|
||||
ssize_t len = Buffer::Length(args[1]);
|
||||
|
||||
String::Utf8Value passphrase(args[2]);
|
||||
int padding = args[2]->Uint32Value();
|
||||
|
||||
String::Utf8Value passphrase(args[3]);
|
||||
|
||||
unsigned char* out_value = NULL;
|
||||
size_t out_len = -1;
|
||||
|
@ -3658,6 +3662,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
|||
kbuf,
|
||||
klen,
|
||||
args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
|
||||
padding,
|
||||
reinterpret_cast<const unsigned char*>(buf),
|
||||
len,
|
||||
&out_value,
|
||||
|
|
|
@ -577,6 +577,7 @@ class PublicKeyCipher {
|
|||
static bool Cipher(const char* key_pem,
|
||||
int key_pem_len,
|
||||
const char* passphrase,
|
||||
int padding,
|
||||
const unsigned char* data,
|
||||
int len,
|
||||
unsigned char** out,
|
||||
|
|
|
@ -857,6 +857,30 @@ assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
|
|||
});
|
||||
})();
|
||||
|
||||
function test_rsa(padding) {
|
||||
var input = new Buffer(padding === 'RSA_NO_PADDING' ? 1024 / 8 : 32);
|
||||
for (var i = 0; i < input.length; i++)
|
||||
input[i] = (i * 7 + 11) & 0xff;
|
||||
var bufferToEncrypt = new Buffer(input);
|
||||
|
||||
padding = constants[padding];
|
||||
|
||||
var encryptedBuffer = crypto.publicEncrypt({
|
||||
key: rsaPubPem,
|
||||
padding: padding
|
||||
}, bufferToEncrypt);
|
||||
|
||||
var decryptedBuffer = crypto.privateDecrypt({
|
||||
key: rsaKeyPem,
|
||||
padding: padding
|
||||
}, encryptedBuffer);
|
||||
assert.equal(input, decryptedBuffer.toString());
|
||||
}
|
||||
|
||||
test_rsa('RSA_NO_PADDING');
|
||||
test_rsa('RSA_PKCS1_PADDING');
|
||||
test_rsa('RSA_PKCS1_OAEP_PADDING');
|
||||
|
||||
// Test RSA key signing/verification
|
||||
var rsaSign = crypto.createSign('RSA-SHA1');
|
||||
var rsaVerify = crypto.createVerify('RSA-SHA1');
|
||||
|
|
Загрузка…
Ссылка в новой задаче