Hello my friend!  I think that maybe my code can help.  in cpp and python.
Sincerely,  Satoshi Nakamoto

Cpp Code

#include <iostream>
#include <string>
#include <cryptopp/base64.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/filters.h>
#include <cryptopp/osrng.h>
#include <cryptopp/rsa.h>
#include <cryptopp/sha.h>

using namespace CryptoPP;

std::string rsa_encrypt(const std::string& message, const RSA::PublicKey&
key) {
    AutoSeededRandomPool rng;

    // Pad the message
    size_t messageLength = message.length();
    size_t maxMessageLength = key.MaxMessageLength();
    if (messageLength > maxMessageLength) {
        throw std::length_error("Message too long for key");
    }

    std::vector<byte> paddedMessage(maxMessageLength);
    size_t paddedMessageLength =
key.ApplyPKCS1Padding((byte*)paddedMessage.data(), paddedMessage.size(),
(const byte*)message.data(), messageLength, rng, RSA::ES_PKCS1v15);

    // Encrypt the padded message
    std::vector<byte> encryptedMessage(maxMessageLength);
    size_t encryptedMessageLength = key.Encrypt(rng, (const
byte*)paddedMessage.data(), paddedMessageLength, encryptedMessage.data());

    // Convert the encrypted message to base64
    std::string base64EncryptedMessage;
    StringSource(encryptedMessage.data(), encryptedMessageLength, true, new
Base64Encoder(new StringSink(base64EncryptedMessage)));

    return base64EncryptedMessage;
}

int main() {
    // Generate a key pair
    AutoSeededRandomPool rng;
    InvertibleRSAFunction parameters;
    parameters.GenerateRandomWithKeySize(rng, 4096);
    RSA::PrivateKey privateKey(parameters);
    RSA::PublicKey publicKey(parameters);

    // Encrypt a message
    std::string message = "Hello, world!";
    std::string encryptedMessage = rsa_encrypt(message, publicKey);
    std::cout << "Encrypted message: " << encryptedMessage << std::endl;

    return 0;
}

Python Code

import os
import base64
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256

def rsa_encrypt(message: bytes, public_key: bytes) -> bytes:
    # Load the public key
    key = RSA.import_key(public_key)

    # Pad the message
    target_length = key.size_in_bytes()
    padded_message = _pad_for_encryption(message, target_length)

    # Encrypt the padded message
    cipher = PKCS1_OAEP.new(key, hashAlgo=SHA256)
    encrypted_message = cipher.encrypt(padded_message)

    # Encode the encrypted message in base64
    base64_encrypted_message = base64.b64encode(encrypted_message)

    return base64_encrypted_message

def _pad_for_encryption(message: bytes, target_length: int) -> bytes:
    # Pad the message using PKCS#1 v1.5 padding
    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\x02", os.urandom(padding_length), b"\x00",
message])


Dwight Kulkarni <dwi...@realtime-7.com> schrieb am Mo. 24. Apr. 2023 um
16:01:

> 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 <dwi...@realtime-7.com>
>> 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 cryptopp-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/cryptopp-users/d6e525fc-94ce-4747-a7d0-fd9f899ae726n%40googlegroups.com
> <https://groups.google.com/d/msgid/cryptopp-users/d6e525fc-94ce-4747-a7d0-fd9f899ae726n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 cryptopp-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/cryptopp-users/CAJm61-CRqHDW9jPP5Dbqa8wRcE8ThZt0jrw9%2Bg8tqA8tqAaQzA%40mail.gmail.com.

Reply via email to