May 27, 2019 syntax: publickey, privatekey, err = rsa:generatersakeys(bits, inpkcs8fmt) Generate rsa public key and private key by specifying the number of bits. The inpkcs8fmt is optional. Any random RSA/DSA key you have EVER generated for the purpose of protecting data, creating custom X.509 certificate, etc. May have been exposed without your awareness in the Windows file system. Accessible by anyone who has access to your account. Your disk is being slowly filled with data.
- Generate Rsa Private Key Windows
- Generate Rsa Private Key C String C
- Generate Rsa Private Key C String C
- Openssl Generate Rsa Private Key
- Generate Rsa Key
It’s common knowledge today that a blockchain is a form of a distributed ledger that holds transactions. These transactions are collected in a block and added to the ledger with a reference to the previous block by means of hashes so that a block, once added, can no longer be changed. Well, in theory, a block could change, but given the computing power necessary to calculate a hash for a block and the fact that blockchain is distributed it’s extremely difficult. You would need to have 51% of the computing power to do so (https://learncryptography.com/cryptocurrency/51-attack).
This process of calculating a hash for a block is one part in keeping the blockchain trusted. However, what is stopping users from submitting transactions on funds that they don’t actually own? How is it, that I cannot simply publish a transaction that says “transfer 1000 of this cryptocurrency to someone else”.
To understand what’s stopping us from doing so, we need to look at a second part of blockchain technology: public/private key pairs and using them for signatures.
We will be using C# code and .NET Core to work our way through this concept.
Public/private key pair
Asymmetrical cryptography is a technique that uses pairs of keys:
- A public key, visible to anyone.
- A private key, only known to the owner.
The private key is essentially a randomly generated number. The public key can be derived from that public key using what’s called Elliptic Curve Cryptography. We can use ECC for encryption, digital signatures, pseudo-random generators and other tasks. Bitcoin uses a specific elliptic curve called secp256k1 over the finite (prime) field of (2²⁵⁶-2³²-2⁹-2⁸-2⁷-2⁶-2⁴-1) number of elements, using the generator point (on the curve) G=(x, y) where (in hexadecimal):
x=79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
y=483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
y=483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
Don’t worry, we will not dive any further into the mathematical details of these ECC algorithms. If you want to know more, check out this article: https://eng.paxos.com/blockchain-101-elliptic-curve-cryptography
In simple code, this is what we do to get the public key from a (random) private key:
The method GetPublicKeyFromPrivateKey looks like this:
The classes CurveFp and Point can be found in the Github repository for this article: https://github.com/sander-/working-with-digital-signatures
If you run this code, you will get following output:
Obviously, having 123456789 as a private key is not particularly safe. But from the public key, there is no way to derive the value of the private key.
Signatures
The process of signing a message entails that you generate a hash that is based on your private key. As you know, hashing is a one-way process, so there’s no way to derive the private key from this hash. However, it is possible to verify whether this hash is accurate if you have the public key of the signer. A digital signature scheme typically consists of 3 algorithms:
- A key generation algorithm that selects a private key uniformly at random from a set of possible private keys. The algorithm outputs the private key and a corresponding public key.
- A signing algorithm that, given a message and a private key, produces a signature.
- A signature verifying algorithm that, given the message, public key and signature, either accepts or rejects the message’s claim to authenticity.
In blockchain, the signature algorithm is the Elliptic Curve Digital Signature Algorithm or ECDSA (https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm). We are not diving into the mathematics of this algorithm. We are, however, going to borrow functions from the BouncyCastle framework (https://www.bouncycastle.org/) to work with ECDSA.
The steps to create a signature for a message are simple.
- Write the message to be signed.
- Create a public/private key pair; to generate the public key from the private key we use the secp256k1 algorithm from before.
- Generate the signature for the message using a signer object.
Strictly speaking, to sign a message we only need a private key. However, signing a message and not giving anyone the public key to verify the signature is pretty pointless.
In code, that reads as follows.
Let’s first look at our new method for generating a public key.
For the sake of readability, the return value of the method is base58 encoded (https://en.wikipedia.org/wiki/Base58).
If we call this method we get our public key, based on the private key we gave as input. So, our public/private key pair contains these values respectively:
The method GetSignature is this.
The outcome of this method is again base58 encoded to make it easier to read.
We can pass this message signature to someone else. The other party will obviously not have the private key to recreate that signature. But we can also publish the public key and thereby allow the other party to do two things.
- The other party can verify that the message was signed by the keeper of the private key that belongs to or pairs with the public key.
- The other party can also verify that the message was not changed by someone else that didn’t have this private key.
Either a change in the message or in the public key would immediately be recognized as the signature would no longer match. Only the original creator of the message together with his private key can make it so the signature is valid.
To verify the signature, we use this code.
As you can see, nowhere do we specify the private key. The BouncyCastle framework does most if not all of the heavy lifting here in providing a signer object that uses ECDSA.
Transactions in the blockchain
The fact that we can have messages from a known source and that these messages cannot be altered by a third party is essential to transactions in a blockchain. Instead of an unstructured message, transactions have a clear structure. This structure looks something like this:
Generate Rsa Private Key Windows
The From and To properties of the transaction are not simple addresses. They are public keys that help verify the sender and the content of the transaction. The transaction and its signature can be created like this.
Following this code, you can see that the message is signed by the owner of the private key that pairs with the public key. By verifying the signature, you can prove that:
- The creator of the transaction is the holder of the private key belonging to the sender/creator of the transaction.
- The receiver is the original intended receiver.
- The amount has not been altered.
Changing any of the parameters (FromPublicKey, ToPublicKey or Amount) would invalidate the signature and therefore make the entire transaction invalid. Verifying the transaction is simple.
In summary
Signing is a good way to know something is being done by the correct person. This means we can trust that someone is actually doing what they say they are. In the real world signatures can be faked. The digital ones cannot. Digital signatures act like electronic “fingerprints.” In the form of a coded message, the digital signature securely associates a signer with a message in a recorded transaction. If you want to know person A sent something, make them sign it before moving forward. If there’s any dispute, check the signature. This is a vital part of the blockchain.
The source code for this post can be found at: https://github.com/sander-/working-with-digital-signatures.
-->This walkthrough demonstrates how to encrypt and decrypt content. The code examples are designed for a Windows Forms application. This application does not demonstrate real world scenarios, such as using smart cards. Instead, it demonstrates the fundamentals of encryption and decryption.
This walkthrough uses the following guidelines for encryption:
- Use the RijndaelManaged class, a symmetric algorithm, to encrypt and decrypt data by using its automatically generated Key and IV.
- Use the RSACryptoServiceProvider, an asymmetric algorithm, to encrypt and decrypt the key to the data encrypted by RijndaelManaged. Asymmetric algorithms are best used for smaller amounts of data, such as a key.NoteIf you want to protect data on your computer instead of exchanging encrypted content with other people, consider using the ProtectedData or ProtectedMemory classes.
The following table summarizes the cryptographic tasks in this topic.
Task | Description |
---|---|
Creating a Windows Forms application | Lists the controls that are required to run the application. |
Declaring global objects | Declares string path variables, the CspParameters, and the RSACryptoServiceProvider to have global context of the Form class. |
Creating an asymmetric key | Creates an asymmetric public and private key value pair and assigns it a key container name. |
Encrypting a file | Displays a dialog box to select a file for encryption and encrypts the file. |
Decrypting a file | Displays a dialog box to select an encrypted file for decryption and decrypts the file. |
Getting a private key | Gets the full key pair using the key container name. |
Exporting a public key | Saves the key to an XML file with only public parameters. |
Importing a public key | Loads the key from an XML file into the key container. |
Testing the application | Lists procedures for testing this application. |
Prerequisites
You need the following components to complete this walkthrough:
- References to the System.IO and System.Security.Cryptography namespaces.
Creating a Windows Forms Application
Most of the code examples in this walkthrough are designed to be event handlers for button controls. The following table lists the controls required for the sample application and their required names to match the code examples.
Control | Name | Text property (as needed) |
---|---|---|
Button | buttonEncryptFile | Encrypt File |
Button | buttonDecryptFile | Decrypt File |
Button | buttonCreateAsmKeys | Create Keys |
Button | buttonExportPublicKey | Export Public Key |
Button | buttonImportPublicKey | Import Public Key |
Button | buttonGetPrivateKey | Get Private Key |
Label | label1 | Key not set |
OpenFileDialog | openFileDialog1 | |
OpenFileDialog | openFileDialog2 |
Double-click the buttons in the Visual Studio designer to create their event handlers.
Declaring Global Objects
Add the following code to the Form's constructor. Edit the string variables for your environment and preferences.
Creating an Asymmetric Key
This task creates an asymmetric key that encrypts and decrypts the RijndaelManaged key. This key was used to encrypt the content and it displays the key container name on the label control.
Add the following code as the
Click
event handler for the Create Keys
button (buttonCreateAsmKeys_Click
).Encrypting a File
This task involves two methods: the event handler method for the
Encrypt File
button (buttonEncryptFile_Click
) and the EncryptFile
method. The first method displays a dialog box for selecting a file and passes the file name to the second method, which performs the encryption.The encrypted content, key, and IV are all saved to one FileStream, which is referred to as the encryption package.
The
EncryptFile
method does the following:- Creates a RijndaelManaged symmetric algorithm to encrypt the content.
- Creates an RSACryptoServiceProvider object to encrypt the RijndaelManaged key.
- Uses a CryptoStream object to read and encrypt the FileStream of the source file, in blocks of bytes, into a destination FileStream object for the encrypted file.
- Determines the lengths of the encrypted key and IV, and creates byte arrays of their length values.
- Writes the Key, IV, and their length values to the encrypted package.
The encryption package uses the following format:
Generate Rsa Private Key C String C
- Key length, bytes 0 - 3
- IV length, bytes 4 - 7
- Encrypted key
- IV
- Cipher text
You can use the lengths of the key and IV to determine the starting points and lengths of all parts of the encryption package, which can then be used to decrypt the file.
Add the following code as the
Click
event handler for the Encrypt File
button (buttonEncryptFile_Click
).Add the following
EncryptFile
method to the form.Decrypting a File
This task involves two methods, the event handler method for the
Decrypt File
button (buttonDecryptFile_Click
), and the DecryptFile
method. The first method displays a dialog box for selecting a file and passes its file name to the second method, which performs the decryption.The
Decrypt
method does the following:- Creates a RijndaelManaged symmetric algorithm to decrypt the content.
- Reads the first eight bytes of the FileStream of the encrypted package into byte arrays to obtain the lengths of the encrypted key and the IV.
- Extracts the key and IV from the encryption package into byte arrays.
- Creates an RSACryptoServiceProvider object to decrypt the RijndaelManaged key.
- Uses a CryptoStream object to read and decrypt the cipher text section of the FileStream encryption package, in blocks of bytes, into the FileStream object for the decrypted file. When this is finished, the decryption is completed.
Add the following code as the
Click
event handler for the Decrypt File
button.Add the following
DecryptFile
method to the form.Exporting a Public Key
This task saves the key created by the
Create Keys
button to a file. It exports only the public parameters.This task simulates the scenario of Alice giving Bob her public key so that he can encrypt files for her. He and others who have that public key will not be able to decrypt them because they do not have the full key pair with private parameters.
Add the following code as the
Click
event handler for the Export Public Key
button (buttonExportPublicKey_Click
).Importing a Public Key
This task loads the key with only public parameters, as created by the
Export Public Key
button, and sets it as the key container name.This task simulates the scenario of Bob loading Alice's key with only public parameters so he can encrypt files for her.
Add the following code as the
Click
event handler for the Import Public Key
button (buttonImportPublicKey_Click
).Getting a Private Key
This task sets the key container name to the name of the key created by using the
Create Keys
button. The key container will contain the full key pair with private parameters.This task simulates the scenario of Alice using her private key to decrypt files encrypted by Bob.
Add the following code as the
Click
event handler for the Get Private Key
button (buttonGetPrivateKey_Click
).Testing the Application
After you have built the application, perform the following testing scenarios.
To create keys, encrypt, and decrypt
- Click the
Create Keys
button. The label displays the key name and shows that it is a full key pair. - Click the
Export Public Key
button. Note that exporting the public key parameters does not change the current key. - Click the
Encrypt File
button and select a file. - Click the
Decrypt File
button and select the file just encrypted. - Examine the file just decrypted.
- Close the application and restart it to test retrieving persisted key containers in the next scenario.
Generate Rsa Private Key C String C
To encrypt using the public key
- Click the
Import Public Key
button. The label displays the key name and shows that it is public only. - Click the
Encrypt File
button and select a file. - Click the
Decrypt File
button and select the file just encrypted. This will fail because you must have the private key to decrypt.
This scenario demonstrates having only the public key to encrypt a file for another person. Typically that person would give you only the public key and withhold the private key for decryption.
Openssl Generate Rsa Private Key
To decrypt using the private key
- Click the
Get Private Key
button. The label displays the key name and shows whether it is the full key pair. - Click the
Decrypt File
button and select the file just encrypted. This will be successful because you have the full key pair to decrypt.