stefko
4/14/2006 12:15:00 PM
Hi folks,
I don't know if this is a bug, but it seems to me like this. This is
when PKCS#1 padding is used. I haven't tried it with other types of
paddig.
I'll give an example of what I mean:
------------------------ cut -----------------------------
require 'openssl'
include Openssl
include PKey
p rsa = PKey::RSA.new(512)
str = "a string longer than 53 bytes. a string longer than 53 bytes. a
string longer than 53 bytes.a string longer than 53 bytes."
p enc = rsa.public_encrypt(str)
p dec = rsa.private_decrypt(enc)
------------------------------ cut -----------------------------
And this crashes with the error :
public_encrypt: data too large for key size (Openssl::PKey::RSAError)
I've searched through Ruby CVS for openssl extensions. here is the
problematic line:
buf_len = RSA_public_encrypt(RSTRING(buffer)->len,
RSTRING(buffer)->ptr,
RSTRING(str)->ptr, pkey->pkey.rsa,
pad);
The problem comes from the internal workings of rsa encryption with
PKCS#1 padding. I don't know the details, but the main point is that
one should not give this function more than RSA_size(rsa) - 11 bytes at
once. The input string should be divided into smaller chunks which are
given to the encrypt function.
Here is what I mean in C code :
-------------------------------- cut
-----------------------------------------
int rsa_size = RSA_size(rsa);
int block_size = rsa_size - 12;
int blocks = msg_len/block_size;
int rest = msg_len % block_size;
int enc_len = 0;
unsigned char* enc = 0;
int curr_len = 0;
int i = 0;
if (0 == rest) {
enc = malloc(blocks*rsa_size + 1);
}
else {
enc = malloc((blocks+1)*rsa_size + 1);
}
for (i = 0; i < blocks; i++) {
if (0 > (curr_len = RSA_public_encrypt(block_size , msg +
i*block_size, enc + i*rsa_size, _rsa, RSA_PKCS1_PADDING))) {
goto err;
}
enc_len += curr_len;
}
if (0 != rest) {
if (0 > (curr_len = RSA_public_encrypt(rest , msg + i*block_size, enc
+ i*rsa_size, _rsa, RSA_PKCS1_PADDING))) {
goto err;
}
enc_len += curr_len;
}
-------------------------------- cut ---------------------------------
This code works fine in a C programme.
I suppose a similar issue exists is applicable to the decrypting
functions.