React native RSA encryption with a public PEM or SSLeay key - npm

I am trying to find a working javascript library for react-native that will allow RSA public key encryption in PEM format.
I am not an expert in encryption and just starting out with react-native so please excuse me if i happened to miss something obvious.
So far i have tryed
react-native-rsa as recomended by this post
and
react-native-rsa-util.
I couldn't get react-native-rsa-util to work and react-native-rsa doesn't seem to accept public PEM keys but only keys in the JWK format.
The only reason i am not willing to use the JWK format is that i cannot find a PHP library that will decrypt the incoming message with a JWK key.
I would highly appreciate any help / pointers.
Thanks alot

I wrote a PHP library that supports JWT encryption/decryption with a lot of other useful features including compression.
All algorithms referenced in the RFC7518 and JWK/JWKSet are supported.
What you can do is convert your PEM key into JWK with my library:
<?php
use Jose\Factory\JWKFactory;
$jwk = JWKFactory::createFromKeyFile('/path/to/my/key.pem');
var_dump($jwk->getAll());
And to decrypt a JWT with your JWK and my library:
use Jose\Loader;
$input = 'eyJhbGciOiJS...';
$loader = new Loader();
$jwe = $loader->loadAndDecryptUsingKey($input, $jwk, ['RSA-OAEP-256'], ['A256CBC-HS512']); // The list of accepted key and content encryption algorithms depends on your needs
The variable $jwe is now JWE Object.
You can get the payload by calling $jwe->getPayload();
Do not hesitate to contact me on the dedicated Gitter channel if needed.

Related

Decrypting cognito codes with KMS client from aws-sdk-v3

I am following this instruction to implement custom message sender in Cognito https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-sms-sender.html
All works well with similar code (I use Typescript on AWS Lambda):
import {buildClient, CommitmentPolicy, KmsKeyringNode} from '#aws-crypto/client-node';
import b64 from 'base64-js';
const {decrypt} = buildClient(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT);
const keyring = new KmsKeyringNode({keyIds: ["my-key-arn"]});
...
const {plaintext} = await decrypt(keyring, b64.toByteArray(event.request.code));
console.log(plainttext.toString()) // prints plain text exactly as I need
However, this library #aws-crypto/client-node makes my bundle really huge, almost 20MB! Probably because it depends on some of older AWS libs...
I used to use modular libraries like #aws-sdk/xxx which indeed give much smaller bundles.
I have found that for encrypt/decrypt I can use #aws-sdk/client-kms. But it doesn't work!
I am trying the following code:
import {KMSClient, DecryptCommand} from "#aws-sdk/client-kms";
import b64 from 'base64-js';
const client = new KMSClient;
await client.send(new DecryptCommand({CiphertextBlob: b64.toByteArray(event.request.code), KeyId: 'my-key-arn'}))
Which gives me an error:
InvalidCiphertextException: UnknownError
at deserializeAws_json1_1InvalidCiphertextExceptionResponse (/projectdir/node_modules/#aws-sdk/client-kms/dist-cjs/protocols/Aws_json1_1.js:3157:23)
at deserializeAws_json1_1DecryptCommandError (/projectdir/node_modules/#aws-sdk/client-kms/dist-cjs/protocols/Aws_json1_1.js:850:25)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /projectdir/node_modules/#aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
at async /projectdir/node_modules/#aws-sdk/middleware-signing/dist-cjs/middleware.js:14:20
at async StandardRetryStrategy.retry (/projectdir/node_modules/#aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)
at async /projectdir/node_modules/#aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
at async REPL7:1:33 {
'$fault': 'client',
'$metadata': {
httpStatusCode: 400,
requestId: '<uuid>',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
__type: 'InvalidCiphertextException'
}
What am I doing wrong? Does this KMSClient support what I need?
I have also tried AWS CLI aws kms decrypt --ciphertext-blob ... command, gives me exactly same response. Though if I encrypt and decrypt any random message like "hello world", it works like a charm.
What am I doing wrong and what is so special about Cognito code ciphertext so I have to decrypt it somehow another way?
Short answer: Cognito does not use KMS to encrypt the text, it uses the Encryption SDK. So you cannot use KMS to decrypt Cognito ciphertext.
Longer answer: I spent the past day trying to get a Python email-sender-trigger function working against Cognito using boto3 and the KMS client until I found another post (somewhere?) explaining that Cognito does not encrypt data using KMS, rather the Encryption SDK. Of course these two encryption mechanisms are not compatible.
For JavaScript and Node.js applications, it looks like you have an alternative to including the entire crypto-client: https://www.npmjs.com/package/#aws-crypto/decrypt-node
If all you are doing is decrypting, the above package will let you decrypt using the Encryption SDK and it's only 159KB.
I have managed to solve my task. I have realized that indeed it does not simply uses KMS to encrypt the text, the encryption/decryption process is much more complicated.
There is reference page https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html
It describes how the message looks like, with all the headers and body, with IV, AAD, keys, etc... I have written my own script to parse it all and properly decrypt, it worked! Probably it's too long to share... I suggest to use the reference instead. Hopefully in future they will publish proper modular version of SDK.
The one from '#aws-crypto' didn't work for me, probably doesn't support all the protocols properly. This might be not the truth at the moment you are reading it.

How can one encrypt content using RSA for Chilkat in C# and decrypt it in Java?

UPDATE
I see that lots of people find my question too long (because there is lots to explain), read the first sentence and then just think that I'm going on the worst tangent possible without seeing the entire question. If the question isn't clear enough please let me know. I'm trying to condense it in the simplest way and not to cause any confusion.
The reason for the public key decryption is to achieve a form of digital signing where the recipient decrypts the encrypted content to reveal a hash value. I didn't see the need to mention this in the question as I wanted to find out how to perform this operation in its basic form. However to avoid any further concerns and warnings around what RSA is all about and that public key decryption is bad, I updated my question with that disclaimer.
BACKGROUND
I have written a C# application that uses the Chilkat's RSA library to take content and encrypt it using a personal Private Key.
Then I would like to use a public website to allow someone to decrypt that very content (that's encrypted) by using an associated public key.
Now, I found a 3rd party website (and there are not a lot of them, BTW) that allows you to decrypt content using a RSA public key (https://www.devglan.com/online-tools/rsa-encryption-decryption).
Unfortunately when I try to use it, I get a "Decrypt error".
Here is a sample setup. I have generated my own personal Public & Private Key pairs. In my C# application, I'm taking a string and encrypting it with a private key and encoding it using Base64.
const string originalContent = "This !s original c0nt3nt";
var rsa = new Chilkat.Rsa();
rsa.GenerateKey(2048);
var encryptedBytes = rsa.EncryptBytes(Encoding.UTF8.GetBytes(originalContent), true);
var encryptedEncodedString = Convert.ToBase64String(encryptedBytes);
Console.WriteLine($"Encrypted:{Environment.NewLine}{encryptedEncodedString}");
Console.WriteLine();
var privateKeyBytes = rsa.ExportPrivateKeyObj().GetPkcs8();
var privateKeyEncodedString = Convert.ToBase64String(privateKeyBytes);
Console.WriteLine($"Private Key:{Environment.NewLine}{privateKeyEncodedString}");
Console.WriteLine();
var publicKeyBytes = rsa.ExportPublicKeyObj().GetDer(false);
var publicKeyEncodedString = Convert.ToBase64String(publicKeyBytes);
Console.WriteLine($"Public Key:{Environment.NewLine}{publicKeyEncodedString}");
Console.WriteLine();
var decyptedContentBytes = rsa.DecryptBytes(encryptedBytes, false);
var decryptedContentString = Encoding.UTF8.GetString(decyptedContentBytes);
Console.WriteLine($"Decrypted:{Environment.NewLine}{decryptedContentString}");
Console.WriteLine();
Console.WriteLine("Press ENTER to quit");
Console.ReadLine();
This sample console app will write out all the necessary information needed to use for the next part of the process and to demonstrate that in principle it works as expected.
Example:
Here are the sample values from the console window:
ENCRYPTED CONTENT
H5JTsGhune1n3WWSPjwVJuUwp70Hsh1Ojaa0NFCVyq0qMjVPMxnknexOG/+HZDrIYsZM7EnPulpmihJk4QyLM8T2KNQIhbWuMHvzgHYlcPJdXpGZhAxwfklL4HP0iRUUXJBsJcS/2XoUDZ6elUoMIFY9cDB4O+WFxKS/5vzLEukTLbQ3aEBNg3xaf9fg12F8LcMxZ3GDsk0W9b6oJci09NTxXd6KKes0RM1hnOhw6bu0U33ZLF3sa0nH9Kdf8w23PoKc/tl12Jsa8N1A4OjaT5910UF8FRH6OkAbNKnxqXcL7+V4HVuHchi3ghuFivAW57boLeHr7OG7wOEC/gfPOw==
PRIVATE KEY
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8xYcNXckXf1X4Kd6qE5c7pddfWdKo71mcwZWskuaq+wq3FTcCTAedo/Vcx8Vxn+RMn5XE7QCDzcAAN0K/BzQsoU81myRzZ+bKP+TJ5HH0jClCUMj+ideEm0fay873jnbG0hKEOJPVxPWwKq3jvDLLmWrdgvd/UiDStDm286SFKfMlLWkSw8YIc5nXsthAgP0hv8Nj7UDKvTEG5o3boTuhG1JQARCEXP0fTdIiv0cEFlSN3KkgF4KDf32Vt2x57N/+PJXpQvcECkLwPpBAq/aM0qbtgeiILxavfBJRwQ5zXDUmZHepvSjK6KIYQsTavQQLDXnFKuXa2fxOJHIlys6pAgMBAAECggEBAI0ZMBtDkL2phj7aPP7vaclB6rvwzc9MKLVM1W2K2DPRNW8nwlhLMB4aoZnaELEfjGvhlPb/F7VtIyiGJbPX1J3PbP9qmVJRxWZDX+WwhaT+5xAUhkgMDDWoQ4s9b9QGfq2Z9BE0oPvWHraxEAz7bRRV9lTgQdK/Np2H7OPdNYn6SW8qVgAukgTBqVno4VDbC34bJwal0e63oBFFfensWlhPtDUQB/uQX7UiRfEkxL+CNuqVLDoAeXWmSVWOPlDTKVu1y1bzfA+WMOKHm1ndq21I07TUPf9FcgYdKf4yKpWvMfVeDev6Oo/2mlac+vrJO571S+h4a5m79jUhCeJwX4kCgYEA7q5hrNtMbErA6dgEOG+KpFTaeqbknwtcykVApEvHt4LKULedAvwkORu65acKFYkxbMt19Fx7ligGxg0yOQRWX1BXK1XOCo9eYOjvOVlbRqBywLIbegehoZQ0LoSsdRcOvFq7EbMV3BaxCmxgpnrCZ75VaCYUMzylIduPWKeT9xcCgYEAyngNIIgsXfpCI+HHILNpprFfS2JBBGPx8N/d9cXahKCJhxrMe8K64CSMyxTwum5DXjJnbE4QBsoowRZTCEF6JUBagRM/pQrVX/CK//oyUUaa5+1S/0OxlUevXR7TD6gcpGNEdPjruc+gZzhfKFuWh+V9mJQUviqm3RjAcEdHAD8CgYBL0kOfGM8vO5QK9R9qGiztxTLecbQAvihM7TD6wEQCjN7eQ2Xyc8zCA4gcujKe4sU7rWqcJODxs2drdPe2WyVhA/GdB5X7js3JdVXBXxx61C9//VRzMIds/9qPyH/MdnWs6hmxJrXUA7Vb/U+6sxacxD73ZdlW6XX/ynLAFAQSIwKBgQCk4i12j87p3ZMdW5HprJJeoNYFMwfVxnrSec1tiGoTVhWJxCZAp22+eaV7ARumB4OvY4bcKZpdnSahUEfgUkphqc3Kjd1nz7HCxsa7/YoarFAcjiXoIb2t30oNoLurZXGl4f1u8QQvNsnfJYZA/I1TMG4e4oEd+OgY6D5XcYR9ywKBgGdaZmoBieiw0NkbijjgQZ0WILDmrIYdsSp4HMp6XDeVvdMb/qYg2jTnvVyqMSb8NdfCOB0GT19r1isQX9RnUgxPikJbVLj8WjAQjHT28mtmRn+Ju/3KT75RJ/LHY3SySNMOgTW75X2u8v0ELdEiiOmc/vTkCYoS/oqp92ELjT1Y
PUBLIC KEY
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvMWHDV3JF39V+CneqhOXO6XXX1nSqO9ZnMGVrJLmqvsKtxU3AkwHnaP1XMfFcZ/kTJ+VxO0Ag83AADdCvwc0LKFPNZskc2fmyj/kyeRx9IwpQlDI/onXhJtH2svO9452xtIShDiT1cT1sCqt47wyy5lq3YL3f1Ig0rQ5tvOkhSnzJS1pEsPGCHOZ17LYQID9Ib/DY+1Ayr0xBuaN26E7oRtSUAEQhFz9H03SIr9HBBZUjdypIBeCg399lbdseezf/jyV6UL3BApC8D6QQKv2jNKm7YHoiC8Wr3wSUcEOc1w1JmR3qb0oyuiiGELE2r0ECw15xSrl2tn8TiRyJcrOqQIDAQAB
WEBSITE PUBLIC KEY DECRYPTION ATTEMPT
Now, when I go to the website (mentioned above) I paste in my encrypted content in the encrypted content text block and I paste my public key that I generated in the text block underneath it and set the RSA Key Type to Public Key. But it fails.
SECOND ATTEMPT
But...
I have done some troubleshooting by taking my personal Private & Public keys that I generated and I use the website to perform the encryption & decryption with my keys and I'm able to encrypt my string and decrypt that encrypted content successfully which leads me to believe that somehow my Chilkat encryption setup is not fully aligned with the one that the website uses.
WHAT I NOTICED
So I started reading what the website had to offer and the author of the page posted an explanation on how to accomplish this (https://www.devglan.com/java8/rsa-encryption-decryption-java) which uses the Java RSA libraries under the hood. Apparently, there are two Java RSA ciphers that can be used "RSA" and "RSA/ECB/PKCS1Padding".
I am not so familiar with the Java libs and I know enough of cryptography to know how to get things done but there are lots of technical aspects that are still unclear to me as to help me figure out where to go next.
QUESTION
My question is, is there anything in Chilkat that I need to setup so that it can encrypt content that would allow a Java application (like the website link posted above) to be able to decrypt? (of course Chilkat needs to be able to decrypt it as well)
A message that has been encrypted with the private key using the Chilkat-library cannot be decrypted with the public key using Java (at least not with the standard SunJCE-provider) or the java-based web-site, since different padding variants are used on both sides.
The prerequisite for a successful decryption is that both encryption and decryption use the same padding variant. The same applies to signing and verification.
There are two variants of the PKCS1-v1.5-padding described in RFC8017: One is RSAES-PKCS1-v1_5, which is used in the context of encryption and decryption, and the other is RSASSA-PKCS1-v1_5, which is used in the context of signing and verifying. RSAES-PKCS1-v1_5 is non-deterministic, i.e. repeated encryption of the same plaintext with the same key always generates different ciphertexts. RSASSA-PKCS1-v1_5 is deterministic, that is, it always generates the same ciphertext under the mentioned conditions.
Since the padding variant depends on the respective platform/library, a general statement is not possible. However, for the Chilkat-library and Java (standard SunJCE provider) the following applies (PKCS1-v1.5-padding assumed):
The methods that Chilkat provides in the context of encryption/decryption use RSAES-PKCS1-v1_5 regardless of whether the public or private key is used for encryption. Analog methods also exist in the context of signing/verifying. These use RSASSA-PKCS1-v1_5.
To check this, the padding variant can be determined by setting the Chilkat.Rsa#NoUnpad flag to true, so that the padding is not removed during decryption. Another option for a test is to repeatedly encrypt the same plaintext with the same key. Since RSAES-PKCS1-v1_5 is probabilistic, different ciphertexts are generated each time.
In Java, the Cipher-class determines which padding variant is used based on the mode (encryption or decryption) and the key type used (private or public). For encryption with the public key and decryption with the private key, RSAES-PKCS1-v1_5 is used. For encryption with the private key and decryption with the public key, RSASSA-PKCS1-v1_5 is used. For signing/verifying, Java provides the Signature-class which uses RSASSA-PKCS1-v1_5.
To check this, proceed as described above. In Java, you can prevent the padding from being removed with RSA/ECB/NoPadding during decryption.
Since in the context of encryption/decryption the public key is used for encryption and the private key is used for decryption, and dedicated classes or methods are used in the context of signing/verifying, there are no or few use cases for direct encryption with the private key and decryption with the public key. Furthermore or maybe because of that these processes are not uniformly implemented in the libraries as you can see in the example of the Chilkat-library and Java.
Altogether three cases can be distinguished for the Chilkat-library and Java:
Within the same library/language, encryption can be performed with the public or private key and decryption with the respective counterpart. For this reason the encryption and decryption on the web site (using Java) works in the posted example Second Attempt: Both the encryption with the private key and the decryption with the public key use RSASSA-PKCS1-v1_5.
If in the Chilkat-code the public key is used for encryption and in Java the private key is used for decryption, RSAES-PKCS1-v1_5 is used for both encryption and decryption, which is why decryption works.
However, if in the Chilkat-code the private key is used for encryption and in Java the public key is used for decryption, RSAES-PKCS1-v1_5 is used for encryption and RSASSA-PKCS1-v1_5 is used for decryption. Both padding variants therefore differ and decryption fails. This corresponds to the scenario described in the question.
After this explanation now to your question: My question is, is there anything in Chilkat that I need to setup so that it can encrypt content that would allow a Java application (like the website link posted above) to be able to decrypt? Since the Java-code uses RSASSA-PKCS1-v1_5 for decryption with a public key, it would be necessary for compatibility to change the padding variant in the Chilkat-code from RSAES-PKCS1-v1_5 to RSASSA-PKCS1-v1_5 in the context of encryption/decryption. If you look at Chilkat's RSA-methods, it seems that this is not intended, but that the logic for determining the padding variant is hard coded (as probably with most libraries). You can only choose between PKCS1-v1.5-padding and OAEP for padding. This means that a message encrypted with the private key using the Chilkat-code cannot be decrypted with the public key in Java or on the website.
What are the alternatives? According to the question, the goal is: The reason for the public key decryption is to achieve a form of digital signing where the recipient decrypts the encrypted content to reveal a hash value.
Here it would be a good idea to create a standard signature on the Chilkat-side, e.g. with signBytes. The hash of the data is created automatically and RSASSA-PKCS1-v1_5 is used as padding variant (if the data are already hashed, the method signHash can be used). On the Java-side, this signature can be verified. Alternatively, the signature can be decrypted with the public key, which allows the hash value to be determined, since Java uses the padding variant RSASSA-PKCS1-v1_5 in both cases. Decryption is also possible on the web site, but the decrypted data are not displayed properly because they are only given as a string (which does not produce any meaningful output because of the arbitrary byte-sequences in a hash) and the encoding cannot be changed to hexadecimal or Base64.
Another possibility might be to use Chilkat on the Java-side as well. Probably Chilkat uses a uniform logic across platforms (which I didn't verify however).
I'm going to (hopefully) answer this question after only reading the 1st part of it. I got to the point where you wrote "... I'm taking a string and encrypting it with a private key ...", and this raised the red flag.
Public key encryption should be where you encrypt using the recipient's public key. The private key is used to decrypt. The point of encryption is that only the intended recipient can decrypt and view the message. With public/private key pairs, you can provide your public key to anybody, but you are in sole possession of your private key. Therefore, anybody can use your public key to encrypt a message intended for you, but you are the only one who can decrypt. This makes sense.
Signing is the opposite: You use your private key to sign, and anybody can verify using your public key. A signature can optionally contain the signed data, so that the act of verifying the signature also extracts the original data. Thus, you verify that (1) the data could only have been signed by the holder of the private key, (2) the data was not modified, and (3) you recover the original data.
Chilkat's API provides the ability to use the public/private keys in the opposite way, which doesn't make any sense, but was needed because there are systems "out there" that do things that make no sense, and Chilkat was needed to perform the opposite. (It makes no sense to encrypt something that anybody can decrypt.)
I think the code behind the devglan website is not capable of doing the RSA encrypt/decrypt in the opposite way. You would need to encrypt using your public key, and then give your private key to the other person.
Or.. you could instead create an "opaque signature" using Chilkat, which is a signature containing the data, and then find the devglan online tool to verify/extract the data from the PKCS7 signature (if the devglan tool exists). This way you can keep your private key and give the public key to the recipient.
Finally.. it seems to me that you're really treating the public/private key as a shared secret -- i.e. a secret only shared between sender and receiver. In that case, why bother using RSA at all? (Remember, RSA is only for encrypting/decrypting small amounts of data. The max number of bytes you can encrypt is equal to the key size minus some overhead. So if you have a 2048-bit key, then you can maximally encrypt 2048/8 bytes minus the overhead used in padding, which is on the order of 20 bytes or so.) If semantically you just have a shared secret, then you might simplify and use symmetric encryption (AES) where the secret key is just a random bunch of bytes and you have no data size limit.

Send RSA public key over socket them import it for encryption [VB .NET]

I'm writing that generates public and private key pair, then send the public key over the socket to another programs to be used to encrypt string data.
I'm using RSA in VB.NET and I was able to generate the required keys:
My public key v+u4Lt4nyLXincU+wbReOTU3nwiTZ7MlFkA7cytLOjuviHrAdnaVAV8+WoFhy9nADGtk1K0OLAE1ZwGzt/kgUw==
My question is: is the public key enough for encryption by other users? and if so, how can I import it to RSA parameters to encrypt data?
Edit:
I used the following code in an attempt to import the public key but it failed:
Dim Parameters As New RSAParameters
Parameters.Modulus = encoder.GetBytes(publicKey)
RSA.ImportParameters(Parameters)
My question is: is the public key enough for encryption by other
users?
The answer is as so often: It depends.
The way you describe your proposed protocol this would be widely open to man-in-the-middle-attacks. Eve could just intercept the message on the wire and replace the key by her own.
From a theoretical point of view, it is sufficient to encrypt data. However, to be useful in real world scenarios, you have to use symmetric encryption as well.
So here is my advice:
Don't do your own protocols if you have to ask such questions. Never. Not once. Use Well known, established technology like TLS!
I had a similar project in VB.net, you will not be able to send messages of a large length because if you are using 2048bit RSA, the maximum size of data you would be able to send would be 245 bytes. https://security.stackexchange.com/questions/33434/rsa-maximum-bytes-to-encrypt-comparison-to-aes-in-terms-of-security
I used the RSA public key so each client would use AES encryption and pass their own keys which are encrypted with RSA, the server would then decrypt the key and use that to resolve data. This uses both asymmetric(RSA) and symmetric encryption(AES). Here is a link with a useful video that explains this when I was doing this project. https://www.youtube.com/watch?v=6H_9l9N3IXU&t=271s
The way I imported the keys was using the .toXMLString and .fromXMLString in the RSA CryptoServiceProvider. Here is a great link explaining it, probably doing a better job that I could. https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsa.toxmlstring(v=vs.110).aspx
I found this page that was very useful for me here
Also I found that I was making the mistake of converting the encrypted byte array to string after encryption then back to byte array just before decryption. The last byte array didn't have the same size as the original.

Phpseclib Private key in Vb.net

I am trying to decrypt a RSA encrypted string, which i encrypted with phpseclib, with vb.net.
The problem: I generated a keypair (public and private) with phpseclib and enrcypted the string with php and publickey. Now i want to decrypt this with a simple vb.net tool. but i can't load the private key i generated with phpseclib...
Can anybody help me, how to import or load the private key into vb.net, so that i can decrypt messages?
Thanks!
The Code:
phpseclib and vb.net
You didn't actually post your code.
In any event, your key is probably just not in the right format. In my experience, .NET usually likes keys to be in an XML format, which you can have phpseclib make for you thusly:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);
extract($rsa->createKey());
echo $privatekey;
?>

Encrypting a file with RSA in Visual Basic .NET

I'm just getting started with Visual Basic .NET and I'm currently stuck on the following problem: how can I encrypt/decrypt a file with asymmetric encryption?
Essentially, I'm trying to figure out how I can write the following pseudocode in VB:
Function EncryptFile(path_to_file_to_encrypt, public_key)
file = ReadFile(path_to_file_to_encrypt)
encrypted_file = Encrypt(file, public_key)
SaveToDisk(encrypted_file, "C:\Encrypted\encryptedfile.xxx")
End Function
Function DecryptFile(path_to_encrypted_file, private_key)
encrypted_file = ReadFile(path_to_encrypted_file)
file = Decrypt(file, private_key)
SaveToDisk(file, "C:\Decrypted\file.xxx")
End Function
The file I'm encrypting/decrypting is an Access database file (i.e. binary), if that makes any difference.
I understand there are containers for private keys, but it looks like the MSDN tutorial is sufficient for me to figure this bit out. I assume I can hard-code the public key in my code (it won't be changing).
Any help would be appreciated!
Usually, an RSA "key encryption key" is used to encrypt a "content encryption key" for a symmetric algorithm. That content encryption key is used to encrypt the file.
Protocols like SSL, S/MIME, and PGP can use this approach (sometimes called key transport). Asymmetric cryptography is very, very slow compared to symmetric algorithms.
Something like Chilkat's S/MIME library for VB.NET could handle this task.