BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 16, 2020, 07:38:33 PM Last edit: November 27, 2020, 08:41:20 AM by BlackHatCoiner Merited by vapourminer (2), DdmrDdmr (1) |
|
OgNasty's thread created me some interest about encryption. Since I'm a beginner to PGP and there are many forum experts that have a high knowledge on this topic, I couldn't find a better category to create it. Both PGP and bitcoin's addresses use elliptic curve cryptography for proving the ownership of public keys without having to reveal their private keys, something really amazing. Although, I see that they don't work the same way. For example, in bitcoin I generate a private ECDSA Key and then with the x and y I get a public key. On gobittest I can generate addresses with chosen private keys. On PGP's kleopatra I haven't figured it out if that's possible. The software uses randomness to choose you a private key for your OpenPGP key pair. You'll tell me, why? Can you generate a chosen private key on Bitcoin Core? No, but I can import it. On PGP I don't know a way of importing a private key other than kleopatra. I'm like 89.8% sure that I'm what asking is something dumb. [Title of the thread was changed from "About PGP" to "PGP Questions [From hex to pem]")
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 17, 2020, 10:23:08 AM Merited by vapourminer (2) |
|
gpg --import is your friend. You can use it to import public keys and also private keys, both don't necessarily have to be present at the same time. Or gpg --import publickey.pub I don't use Kleopatra for key management I directly use the gpg program. Regarding your question about generating public keys from private keys, GPG actually creates RSA keys by default - to make ECDSA keys you need to have version 2.1 or greater and pass the --expert --full-gen-key options, then you can select ECC curves. Theoretically it should be possible to derive the public key but no one seemed to have made a utility or library to do that, libgcrypt is too hard for people to understand. I studied it and couldn't find where x and y are generated.
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 21, 2020, 07:11:52 PM Last edit: November 21, 2020, 07:25:45 PM by BlackHatCoiner |
|
pass the --expert --full-gen-key options, then you can select ECC curves. I successfully did that, and yes I got my secp256k1 public key, but what I want to achieve is to import a hexadecimal private key and convert it to an RSA secret key. Then from the secret key I can derive the public key block. Your --import command does not refer to hexadecimal numbers. I wonder if it's possible, if not my project is ruined. I know that RSA chooses a random number to generate me my secret key and I believe there is a way to do what I'm saying.
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 21, 2020, 09:06:06 PM |
|
pass the --expert --full-gen-key options, then you can select ECC curves. I successfully did that, and yes I got my secp256k1 public key, but what I want to achieve is to import a hexadecimal private key and convert it to an RSA secret key. Then from the secret key I can derive the public key block. Your --import command does not refer to hexadecimal numbers. I wonder if it's possible, if not my project is ruined. I know that RSA chooses a random number to generate me my secret key and I believe there is a way to do what I'm saying. GPG doesn't have a way to do this built-in but if you got a Linux terminal somewhere you can use xxd to convert the hex key into binary and then use openssl command line utility to make an RSA key out of it. Both should be installed by default. There's a great stack overflow question that answers basically what you're asking for. https://stackoverflow.com/q/54401343/12452330With your hex input file (rsa-key-hex.txt), you can do the following - Convert it to binary (which is actually DER format) - xxd -r -ps rsa-key-hex.txt rsa-key.der Print the DER private key - openssl pkey -in rsa-key.der -inform der -noout -text Convert it to PEM - openssl pkey -in rsa-key.der -inform der -out rsa-key.pem -outform pem Sign some input using the private key - echo "Some Input" | openssl dgst -sha256 -sign rsa-key.pem > signature.dat Extract the public key - openssl pkey -in rsa-key.pem -pubout -out rsa-key-pub.pem Check signature using the public key - echo "Some Input" | openssl dgst -sha256 -verify rsa-key-pub.pem -signature signature.dat Alternatively, check signature using the private key directly - echo "Some Input" | openssl dgst -sha256 -prverify rsa-key.pem -signature signature.dat
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 21, 2020, 10:01:17 PM |
|
It seems too complicated for me. I tried it on my ubuntu but got several errors. What makes me worrying is that if it is difficult to do it on the command line, imagine how much difficult it'll be to import a library on visual studio and start performing the functions there...
Since I probably won't finish my project, I was thinking of creating mnemonic for pgp. I didn't find anything on the internet so it may not exist. I would use 2 libraries, one for mnemonic and one for gpg. You would generate a seed and then the private key of the 1st derivation path would be your PGP private key. The problem as you saw was that I needed to convert that 64bit private key to base64 secret key pem.
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 21, 2020, 10:26:09 PM |
|
It seems too complicated for me. I tried it on my ubuntu but got several errors. What makes me worrying is that if it is difficult to do it on the command line, imagine how much difficult it'll be to import a library on visual studio and start performing the functions there...
You only need three commands from the answer I linked above. And to store your private key hex in rsa-key-hex.txt before you begin. Do not put a newline at the end of the file. On WIndows you can run this in a WSL distribution. # This turns the hexadecimal string to a binary string xxd -r -ps rsa-key-hex.txt rsa-key.der # binary string to private key openssl pkey -in rsa-key.der -inform der -out rsa-key.pem -outform pem # extract public key from private key openssl pkey -in rsa-key.pem -pubout -out rsa-key-pub.pem Are you trying to make a Windows program that turns private key hex's to RSA? I found a C++ snippet that mimics the first command running xxd. I made a few modifications to it. #include <iostream> #include <sstream> #include <bitset> #include <string>
#define KEY_LENGTH 2048 /* size of RSA key */
using namespace std;
int main() { string s = "0xA"; /* This is the input */ stringstream ss; ss << hex << s; unsigned n; ss >> n; bitset<KEY_LENGTH> b(n); // outputs "000000000000000000<more zeros follow...>00000000001010" cout << b.to_string() << endl; }
As for OpenSSL, the library for it is here but as a beginner I wouldn't start with that as the library is harder to use than the program. Since I probably won't finish my project, I was thinking of creating mnemonic for pgp. I didn't find anything on the internet so it may not exist. I would use 2 libraries, one for mnemonic and one for gpg. You would generate a seed and then the private key of the 1st derivation path would be your PGP private key. The problem as you saw was that I needed to convert that 64bit private key to base64 secret key pem.
You don't need to convert the private key to pem first. You can decode the mnemonic phrase into the BIP39 seed, then pass the BIP39 seed to the PBKDF2 key stretching function (same as the one bitcoin uses), but with a different key size, in this case the length of your RSA key. There are python modules for these but IDK if C++ libraries for all of these exist. Then you have a private key hex for which you can use the commands above to make an RSA key pair.
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 22, 2020, 06:34:41 AM |
|
Thank you for your help. I don't use C++ since I don't know it. I only use C#, so if I'm not mistaken even if you found a python/c++ library, it won't help my c# program. You don't need to convert the private key to pem first. You can decode the mnemonic phrase into the BIP39 seed, then pass the BIP39 seed to the PBKDF2 key stretching function (same as the one bitcoin uses), but with a different key size, in this case the length of your RSA key. There are python modules for these but IDK if C++ libraries for all of these exist. PBKDF2 key or the first key from derivation path, it doesn't have that much difference does it? Because both are random. The only thing that changes is the size. As for my RSA key. Isn't it much longer than a bitcoin master key?
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 22, 2020, 09:43:16 AM |
|
You don't need to convert the private key to pem first. You can decode the mnemonic phrase into the BIP39 seed, then pass the BIP39 seed to the PBKDF2 key stretching function (same as the one bitcoin uses), but with a different key size, in this case the length of your RSA key. There are python modules for these but IDK if C++ libraries for all of these exist. PBKDF2 key or the first key from derivation path, it doesn't have that much difference does it? Because both are random. The only thing that changes is the size. As for my RSA key. Isn't it much longer than a bitcoin master key? Well... there is a difference, you can stretch the PBKDF2 key to whatever size you want. Without going into too much detail the seed made by PBKDF2 has to be passed to SHA512-HMAC which expects a 512-bit key. Eventually the derivation process returns a 256-bit child key. You can't change the size without also changing the algorithm for deriving keys. You said it yourself, that RSA keys are much longer than master keys. That's why derived keys are unsuitable as entropy for an RSA key.
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 22, 2020, 02:01:31 PM |
|
Even if I successfully find a way to convert hexadecimal numbers to secret keys, how exactly will I convert a secret key to public? On bitcoin there's an analytical guide of how to turn a private key into an address. On PGP, it doesn't seem that simple. Email address, name etc are required to generate the public key. Am I right? Is there any simple guides for pgp too? As far as I've seen, no. As for the commands, I get this error: This is my txt: (1 line)
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 22, 2020, 05:40:22 PM |
|
No no, don't run that last command in your terminal, you're only supposed to use these: # This turns the hexadecimal string to a binary string xxd -r -ps rsa-key-hex.txt rsa-key.der # binary string to private key openssl pkey -in rsa-key.der -inform der -out rsa-key.pem -outform pem # extract public key from private key openssl pkey -in rsa-key.pem -pubout -out rsa-key-pub.pem All that code in my other reply, I just copied and pasted it from the stack overflow answer I linked, it was probably a mistake for me to include it here, because it does other things (that will cause errors) you don't need it to do besides making secret keys. I can make it a bash script if you want and you can save it to a file, if it helps you: https://gist.githubusercontent.com/ZenulAbidin/54b9fe0a4618be855f95f843994086fe/raw/f957cff4da11e0c4d0306cffbeca9bc1ab95ddf2/to_key_pair.shEven if I successfully find a way to convert hexadecimal numbers to secret keys, how exactly will I convert a secret key to public? On bitcoin there's an analytical guide of how to turn a private key into an address. Third command of the script extracts the public key from the generated private key On PGP, it doesn't seem that simple. Email address, name etc are required to generate the public key. Am I right?
You can use a fake email address and name because PGP doesn't validate this data. You can even make a key called and encrypt and sign messages from it perfectly without an actual email address like that. Is there any simple guides for pgp too? As far as I've seen, no.
That is something we can do better at and Kleopatra also isn't the user-friendliest PGP software. Seriously it's unbelievable how badly complex GUIs for PGP are. It shouldn't have to be like this. But you asked for guides, so I'd say GPG4Win has an awesome tutorial for how to encrypt and sign messages with illustrations: https://www.gpg4win.org/doc/en/gpg4win-compendium.html. The documentation in GPG4Win make it simpler to use than Kleopatra by itself, but I agree that a little program that just encrypts/decrypts and signs/verifies a message would be the sweet spot (it unfortunately doesn't exist yet). This is my txt: (1 line)Where did you get that string from? There are not enough characters in that string to make 2048 bits.
|
|
|
|
Saint-loup
Legendary
Offline
Activity: 2786
Merit: 2428
|
|
November 22, 2020, 06:53:54 PM Merited by vapourminer (1) |
|
You don't need to convert the private key to pem first. You can decode the mnemonic phrase into the BIP39 seed, then pass the BIP39 seed to the PBKDF2 key stretching function (same as the one bitcoin uses), but with a different key size, in this case the length of your RSA key. There are python modules for these but IDK if C++ libraries for all of these exist. PBKDF2 key or the first key from derivation path, it doesn't have that much difference does it? Because both are random. The only thing that changes is the size. As for my RSA key. Isn't it much longer than a bitcoin master key? Well... there is a difference, you can stretch the PBKDF2 key to whatever size you want. Without going into too much detail the seed made by PBKDF2 has to be passed to SHA512-HMAC which expects a 512-bit key. Eventually the derivation process returns a 256-bit child key. You can't change the size without also changing the algorithm for deriving keys. You said it yourself, that RSA keys are much longer than master keys. That's why derived keys are unsuitable as entropy for an RSA key. But why he would derive keys? He doesn't need it. Why it wouldn't be ok to just take the 512bit seed he got? https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch05.asciidoc#fig_5_7To create a binary seed from the mnemonic, we use the PBKDF2 function with a mnemonic sentence (in UTF-8 NFKD) used as the password and the string "mnemonic" + passphrase (again in UTF-8 NFKD) used as the salt. The iteration count is set to 2048 and HMAC-SHA512 is used as the pseudo-random function. The length of the derived key is 512 bits (= 64 bytes).
This seed can be later used to generate deterministic wallets using BIP-0032 or similar methods. https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 22, 2020, 07:02:34 PM |
|
You can use a fake email address and name because PGP doesn't validate this data. You can even make a key called and encrypt and sign messages from it perfectly without an actual email address like that. This is obvious, what I don't get is how the name and email will be encrypted along with the public key. Since I'm trying to create such project, simply converting secret key to public key isn't enough. I'll have to convert the secret key with the user credentials (name, email) to public key. I'm picturing that gpg does a function like that to generate a public key: RSA_Algorithm(random_number, name, email) Seriously it's unbelievable how badly complex GUIs for PGP are. It shouldn't have to be like this. But you asked for guides, so I'd say GPG4Win has an awesome tutorial for how to encrypt and sign messages with illustrations: https://www.gpg4win.org/doc/en/gpg4win-compendium.html. The documentation in GPG4Win make it simpler to use than Kleopatra by itself, but I agree that a little program that just encrypts/decrypts and signs/verifies a message would be the sweet spot (it unfortunately doesn't exist yet). One day I sat down and tried to understand how pgp and openssl work. It was like being blind searching on a dark room for a black cat that wasn't there. Where did you get that string from? There are not enough characters in that string to make 2048 bits.
But, that "small" string is supposed to be the private key. In your previous posts you're telling me to put a 512 bit key (or 256), not 2048. Why should it be 2048? Isn't taking a random number between a huge range?
And I should not forget that if these are hard, can't think of how hard it'll be to implement them on c#.
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 22, 2020, 07:53:13 PM |
|
But why he would derive keys? He doesn't need it. Why it wouldn't be ok to just take the 512bit seed he got?
But, that "small" string is supposed to be the private key. In your previous posts you're telling me to put a 512 bit key (or 256), not 2048. Why should it be 2048? Isn't taking a random number between a huge range?
I don't think I was clear enough about the private key length, I was trying to say you should not derive a 512-bit/256-bit key, so I guess that's where the confusion came from. The reason is GPG can only make at least 1024-bit length RSA keys (RSA-1024), but those aren't secure so people make RSA-2048 and RSA-4096 keys instead. what I don't get is how the name and email will be encrypted along with the public key. Since I'm trying to create such project, simply converting secret key to public key isn't enough. I'll have to convert the secret key with the user credentials (name, email) to public key. I'm picturing that gpg does a function like that to generate a public key: RSA_Algorithm(random_number, name, email) The name and email not encrypted in the message, they remain in the public key (nothing in the public key is encrypted). While the fingerprint that points to the public key is embedded in the encrypted file.
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 22, 2020, 08:26:53 PM |
|
I don't think I was clear enough about the private key length, I was trying to say you should not derive a 512-bit/256-bit key, so I guess that's where the confusion came from. Why you shouldn't? Isn't 256-bit secure enough or just impossible for RSA?
|
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 22, 2020, 09:12:54 PM |
|
Okay, so if I understood correctly, I can't implement my idea, because converting a bitcoin (256-bit) private key to an RSA public key would be completely unsecure. Do you have any other idea of making a mnemonic for pgp?
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 22, 2020, 10:46:47 PM |
|
Okay, so if I understood correctly, I can't implement my idea, because converting a bitcoin (256-bit) private key to an RSA public key would be completely unsecure. Do you have any other idea of making a mnemonic for pgp?
Theoretically for a 12 word mnemonic you can use a wordlist with 2^88 words to encode 2048 bits of entropy, and the appropriate amount of BIP39 checksum bits. But this is not practical. A 24 word mneumonic needs a wordlist with 2^44 words to encode the same amount of entropy and checksum. Ditto 48 word mneumonics with a 2^22 wordlist (which is 4194304 words but now the mneumonic length is becoming impractical as well). I made a Jupyter notebook that shows you a table of how big a wordlist you need for varying mnemonic phrase lengths and RSA key sizes, it's probably easier for you to understand. https://colab.research.google.com/drive/1wZSRDxd7md6Qrdd4-iTGyuBFzxWeuPx1?usp=sharingI'll paste the results here: 256 512 1024 2048 4096 12 22.000000 44.000000 88.000000 176.000000 352.000000 24 11.000000 22.000000 44.000000 88.000000 176.000000 36 7.333333 14.666667 29.333333 58.666667 117.333333 48 5.500000 11.000000 22.000000 44.000000 88.000000
The values in the table are the number of bits each word needs to store, so the corresponding wordlist needs to have 2**(number of bits) words in it.
In short, it's not practical to make a mnemonic phrase for RSA keys because of its enormous key size, which happen to be required for its security. They cause the wordlists or phrase lengths to become too large.
|
|
|
|
Saint-loup
Legendary
Offline
Activity: 2786
Merit: 2428
|
|
November 22, 2020, 11:30:05 PM Merited by NotATether (2) |
|
Okay, so if I understood correctly, I can't implement my idea, because converting a bitcoin (256-bit) private key to an RSA public key would be completely unsecure. Do you have any other idea of making a mnemonic for pgp?
Theoretically for a 12 word mnemonic you can use a wordlist with 2^88 words to encode 2048 bits of entropy, and the appropriate amount of BIP39 checksum bits. But this is not practical. A 24 word mneumonic needs a wordlist with 2^44 words to encode the same amount of entropy and checksum. Ditto 48 word mneumonics with a 2^22 wordlist (which is 4194304 words but now the mneumonic length is becoming impractical as well). I made a Jupyter notebook that shows you a table of how big a wordlist you need for varying mnemonic phrase lengths and RSA key sizes, it's probably easier for you to understand. https://colab.research.google.com/drive/1wZSRDxd7md6Qrdd4-iTGyuBFzxWeuPx1?usp=sharingI'll paste the results here: 256 512 1024 2048 4096 12 22.000000 44.000000 88.000000 176.000000 352.000000 24 11.000000 22.000000 44.000000 88.000000 176.000000 36 7.333333 14.666667 29.333333 58.666667 117.333333 48 5.500000 11.000000 22.000000 44.000000 88.000000
The values in the table are the number of bits each word needs to store, so the corresponding wordlist needs to have 2**(number of bits) words in it.
In short, it's not practical to make a mnemonic phrase for RSA keys because of its enormous key size, which happen to be required for its security. They cause the wordlists or phrase lengths to become too large. I'm not sure about that, the keys above have been broken because of their length, but not because of their lack of entropy as I understand, so such large amounts of entropy are maybe not necessary...
|
|
|
|
NotATether
Legendary
Offline
Activity: 1778
Merit: 7360
Top Crypto Casino
|
|
November 23, 2020, 01:40:50 PM Last edit: November 23, 2020, 02:42:19 PM by NotATether Merited by Saint-loup (1) |
|
I'm not sure about that, the keys above have been broken because of their length, but not because of their lack of entropy as I understand, so such large amounts of entropy are maybe not necessary...
This caused me to search on the web for how many bits entropy is needed to make RSA keys, and according to https://crypto.stackexchange.com/questions/48256/how-much-entropy-do-you-need-for-a-secure-certificate-generation , we only need 128 bits regardless of key size. @BlackHatCoiner I must have confused entropy with key size, apparently we don't need such large amounts of entropy (and this huge wordlists) to make a decently sized RSA key, because a brute force attack can only be done on the RSA key itself, not guessing the bits of entropy user because that is unknown, and discarded after the key is made. So maybe mnemonic phrases and bitcoin derived keys are still on the table. We just need to stretch their size big enough for the RSA key generation. So from 128 bits of entropy we expand it to a 2048 bit number from it, the RSA key will now be 2048 bits but an attacker now has to brute force the 2^128 different entropy values instead of the RSA key.
And here's my simple question. Let's take a 256-bit hex number that could be a bitcoin private key: b62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cad Right now it can't be converted to secret key, but what if I just add itself another 7 times? (to succeed the 2048 bits) b62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cad It still can't be brute forced and we can convert it to secret key. Right? Correct.
|
|
|
|
BlackHatCoiner (OP)
Legendary
Offline
Activity: 1694
Merit: 8322
Bitcoin is a royal fork
|
|
November 23, 2020, 02:00:45 PM Last edit: November 23, 2020, 03:39:17 PM by BlackHatCoiner |
|
And here's my simple question. Let's take a 256-bit hex number that could be a bitcoin private key: b62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cad
Right now it can't be converted to secret key, but what if I just add itself another 7 times? (to succeed the 2048 bits) b62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd47 9b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07a e537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02 f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d 3cadb62ff5544f5cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5 cd479b336fdbe26d07ae537b1a7ef0fa02f7a21c52681b20d3cadb62ff5544f5cd479b336fdbe26 d07ae537b1a7ef0fa02f7a21c52681b20d3cad
It still can't be brute forced and we can convert it to secret key. Right?
|
|
|
|
|