Hi Jeffery,
I tried out your code and it works to generate the exact same encrypted
message as Python if I use the Integer approach then change it to bytes.
To make messages comparable, I used the _pad_for_signing code (see below)
to generate exactly the same header.
For Pcks1 v 1.5 it is expecting something like this:
00 01 PADDING 00 MESSAGE --> for signing
00 02 PADDING 00 MESSAGE --> for encryption
where padding_length = key_size - msglength - 3
Three bytes are 00 [01/02] and 00 as above. Padding is randomly
generated for encrytion or set to 0xff for signing and excludes 00 bytes.
Then the padding is 00 terminated.
However, this is not working with the following code from cryptopp. Can
you confirm if the PKCS1v15_Encryptor will produce the same logic as above
? Could it be that the output is base64 encoded again or something rather
than raw bytes, because it is going into a StringSink(..) Maybe it is not
terminating the 00 padding or has the leading 00 02 ?
I can confirm, that the python function decrypts the string but runs into
problems parsing the decrypted output.
std::string encrypt_rsa(std::string message, CryptoPP::RSA::PublicKey key)
{
try{
message = b64encode(message);
CryptoPP::AutoSeededRandomPool rng;
//CryptoPP::RSAES_OAEP_SHA_Encryptor encryptor(key);
CryptoPP::RSAES_PKCS1v15_Encryptor encryptor(key);
std::string ciphertext;
CryptoPP::StringSource(message, true, new CryptoPP::PK_EncryptorFilter(rng,
encryptor, new CryptoPP::StringSink(ciphertext)));
return ciphertext;
}
catch(...)
{
std::cout << "error encrypting RSA";
return "";
}
}
def _pad_for_signing(message: bytes, target_length: int) -> bytes:
r"""Pads the message for signing, returning the padded message.
The padding is always a repetition of FF bytes.
:return: 00 01 PADDING 00 MESSAGE
>>> block = _pad_for_signing(b'hello', 16)
>>> len(block)
16
>>> block[0:2]
b'\x00\x01'
>>> block[-6:]
b'\x00hello'
>>> block[2:-6]
b'\xff\xff\xff\xff\xff\xff\xff\xff'
"""
max_msglength = target_length - 11
msglength = len(message)
if msglength > max_msglength:
raise OverflowError(
"%i bytes needed for message, but there is only"
" space for %i" % (msglength, max_msglength)
)
padding_length = target_length - msglength - 3
return b"".join([b"\x00\x01", padding_length * b"\xff", b"\x00",
message])
def _pad_for_encryption(message: bytes, target_length: int) -> bytes:
r"""Pads the message for encryption, returning the padded message.
:return: 00 02 RANDOM_DATA 00 MESSAGE
>>> block = _pad_for_encryption(b'hello', 16)
>>> len(block)
16
>>> block[0:2]
b'\x00\x02'
>>> block[-6:]
b'\x00hello'
"""
max_msglength = target_length - 11
msglength = len(message)
if msglength > max_msglength:
raise OverflowError(
"%i bytes needed for message, but there is only"
" space for %i" % (msglength, max_msglength)
)
# Get random padding
padding = b""
padding_length = target_length - msglength - 3
# We remove 0-bytes, so we'll end up with less padding than we've asked
for,
# so keep adding data until we're at the correct length.
while len(padding) < padding_length:
needed_bytes = padding_length - len(padding)
# Always read at least 8 bytes more than we need, and trim off the
rest
# after removing the 0-bytes. This increases the chance of getting
# enough bytes, especially when needed_bytes is small
new_padding = os.urandom(needed_bytes + 5)
new_padding = new_padding.replace(b"\x00", b"")
padding = padding + new_padding[:needed_bytes]
assert len(padding) == padding_length
return b"".join([b"\x00\x02", padding, b"\x00", message])
On Friday, April 21, 2023 at 8:51:59 PM UTC-4 Jeffrey Walton wrote:
> On Fri, Apr 21, 2023 at 7:39 PM Dwight Kulkarni <[email protected]>
> wrote:
> >
> > I need to convert Integer to unsigned char array or to vector<unsigned
> char>
> >
> > If I do this:
> > for(int i=0; i<c.ByteCount(); i++){
> > cout << int(c.GetByte(i)) << " ";
> > }
> >
> > The values are not what I expect. Also, is there anything faster than a
> for loop to get the data out ?
>
> The Integer class uses Encode when it needs to format an Integer as a
> byte array for various functions, like DER encoding. You might try
> something like:
>
> #include <iostream>
> #include "integer.h"
> #include "osrng.h"
>
> int main(int argc, char* argv[])
> {
> using namespace CryptoPP;
>
> AutoSeededRandomPool prng;
> Integer n;
>
> n.Randomize(prng, 128);
> const size_t len = n.MinEncodedSize(Integer::UNSIGNED);
>
> std::vector<byte> v;
> v.resize(len);
> n.Encode((byte*)&v[0], v.size(), Integer::UNSIGNED);
>
> std::cout << "Iostream: " << std::hex << n << std::endl;
> std::cout << " Vector: ";
> for(size_t i : v) { std::cout << (i & 0xff); }
> std::cout << std::endl;
>
> return 0;
> }
>
> It will produce output similar to:
>
> jwalton@coffee:~/cryptopp$ g++ -g2 -O3 test.cxx ./libcryptopp.a -o test.exe
> jwalton@coffee:~/cryptopp$ ./test.exe
> Iostream: b32bd756bde62ea5124552714147af6eh
> Vector: b32bd756bde62ea5124552714147af6e
> jwalton@coffee:~/cryptopp$ ./test.exe
> Iostream: fcbf89617f7f1cf55c1016b2355152e9h
> Vector: fcbf89617f7f1cf55c1016b2355152e9
>
> I'll get the example added to the wiki at
> https://www.cryptopp.com/wiki/Integer .
>
> Jeff
>
--
You received this message because you are subscribed to the Google Groups
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/cryptopp-users/d6e525fc-94ce-4747-a7d0-fd9f899ae726n%40googlegroups.com.