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.