I have a public and private key that I receive as strings in Go and need to verify that they are valid keys. The default crypto library is deprecated (I tried it, and it doesn't work; I think my format is too new).
I know I have 2 valid keys are
They were recently generated and
They have been validated through other means
So, how does one actually validate GPG keys in Go? Do I need to deconstruct the key myself?
Related
If I encrypt a file as file1 using openssl, where is the hash of that password stored?
No matter what I Google, the closest I get are instructions to enable root and navigate to /var/db/dslocal/nodes/Default/users directory. Unless I'm just not recognizing it, I am unable to find anything that looks like what I want in there.
If I understand the question correctly (i.e. that it's about encrypting a file with openssl enc -ciphername or the shorthand openssl ciphername), then the answer is: the hash is not stored anywhere.
What happens is that the password (and salt) are run through a hash function to derive an encryption key, and that key is used to encrypt the contents of the file. The key (i.e. the hash) is then discarded.
When you go to decrypt the file, it runs the password you entered and the salt (stored in the file) through the same hash function, and attempts to use that to decrypt the file's contents. If the password is the same as that used to encrypt, you get your original file back. If the password is different, you get back gibberish. openssl might be able to tell it's gibberish if the padding doesn't make sense, but it might not. As the man page says:
All the block ciphers normally use PKCS#5 padding also known as
standard block padding: this allows a rudimentary integrity or
password check to be performed. However since the chance of random
data passing the test is better than 1 in 256 it isn't a very good
test.
I'm using an AES key of type cipher.Block generated by using crypto/aes package with below func:
aesBlock, err := aes.NewCipher(randKey)
I'm using this to encrypt a particular set of data but afterward I want to encrypt aesBlock itself with a Public Key, so that I can store and later decrypt with the asymmetric Private Key. However, I'm having a tough time finding the best way to encrypt aesBlock. Obviously this needs to be reversible so that I can use it to decrypt the previously mentioned data.
The func EncryptOAEP from crypto/aes seems like a good fit, as it takes a *PublicKey, however the msg parameter is of type []byte and my AES key is of type cipher.Block. Not sure a direct conversion is possible or even a good idea.
Any ideas?
As Adrian pointed out in the comments, the solution is simpler than I thought. All you need to do is encrypt and store the randKey. Regenerating the aesBlock with decrypted randKey produces the same results.
In SQLCipher it is possible to provide a database key in two ways: either as a passphrase (with an associated number of PBKDF2 rounds) or as a raw key.
I am trying to find a way get the raw key (given as a 64 character hex string) given the passphrase (an arbitrary string) and number of rounds. I assume the solution lies in somehow performing the PBKDF2 key derivation myself, but I'm not too familiar with how this might work, or if it would produce a value that I could just feed as a raw key to PRAGMA KEY. In addition, the PBKDF2 function appears to take a salt, which I do not know. If I have to, I am sure I can dig into the sqlcipher source code to figure this out, but I'm hoping that there might already be a simple way to do this that I'm missing.
The details on SQLCipher key derivation can be found on the design page. The salt is stored in the first 16 bytes of the database file. You would then use the salt along with the passphrase with an appropriate number of PBKDF2-HMAC-SHA1 rounds (64,000 for SQLCipher 3, 4,000 for earlier versions)
This actually breaks down into a lot of separate questions to understand the overall process.
From what I understand a JWT is just three JSON objects encoded into base64 separately from one another. Then the Base64 strings are separated by periods. This is done purely for "shorter message" purposes?
These include a header, "payload," and signature. The header and payload are 100% available to read by anyone who intercepts them. They are just base64 strings that can be decoded into JSON and read.
Then the MAGIC: The server receives the SIGNATURE, which cannot be decoded. The signature is actually a hash of the header, payload, AND a secret key. So the server takes the header, the payload, and ITS OWN secret key, and makes a hash. If this hash MATCHES the signature that came with the message, the message is trusted. If the signatures DO NOT match, the message is invalid.
My problem with all this? Where are the two separate keys here? It seems that the key used to encrypt the message and the key used to decrypt the message are the same. This is the root of my question - if you answer nothing else, please help with this.
Other than that, I wonder if I understand the process correctly? Also, where is the standard "agreeing on a public key" and then trading "mixtures" of public/private keys occurring here? All I see is the same key being used to encode/decode. But when did the agreement happen? Viewing this in context of .NET and Auth0 btw, but overall q.
Random stuff I watched/read/used if anyone is interested on seeing this q later:
Summary of JWTs: https://scotch.io/tutorials/the-anatomy-of-a-json-web-token
Public-key/Assymetric Cryptography: https://youtu.be/3QnD2c4Xovk
Hashing: http://www.webopedia.com/TERM/H/hashing.html
Base64: http://en.wikipedia.org/wiki/Base64
Firstly, JSON Object Signing and Encryption standards (JOSE) use base64url encoding and not straight base64 encoding, which differs slightly.
JWT header and payload are JSON objects but the signature is not, that's a base64url encoded binary blob
the whole JWT is available to anyone who intercepts it, all 3 parts of it
you're describing a symmetric key algorithm, where sender and receiver use the same shared key; that is just one option for JWTS, another option is to use public/private key pairs for signing/validation/encryption/decryption
As with all crypto, agreement on keys needs to happen out of band.
Then the MAGIC: The server receives the SIGNATURE, which cannot be decoded. The signature is actually a hash of the header, payload, AND
a secret key. So the server takes the header, the payload, and ITS OWN
secret key, and makes a hash. If this hash MATCHES the signature that
came with the message, the message is trusted. If the signatures DO
NOT match, the message is invalid.
There is no magic here. JWT supports four well-known signature and MAC (message authentication code) constructions: HMAC (a symmetric algorithm), and ECDSA, RSASSA-PKCS-v1.5 and RSASSA-PSS (public-key algorithms). Each of these may be used with the SHA-256, SHA-384 or SHA-512 cryptographic digest. See also the table of Cryptographic Algorithms for Digitial Signatures and MACs from RFC 7518 - JSON Web Algorithms (JWA).
My problem with all this? Where are the two separate keys here? It
seems that the key used to encrypt the message and the key used to
decrypt the message are the same. This is the root of my question - if
you answer nothing else, please help with this.
There are not necessarily two separate keys - if a public key algorithms is used, the signature will be created using the server's private key, and verified using the corresponding public key. But if an HMAC algorithm is used, a shared secret key must be used for both signing and verification.
So I have implemented salts and IVs, but the decryption is now a bit buggy. Of course, I need both the salt and IV for decryption as well, but the user can't enter that... I need to be able to store both the salt and IV in the encrypted file, then retrieve the salt and IV when the user is decrypting the file. How would I go about doing this? How would I go about storing and retrieving that data?
As Peter said, the initialization vector and the salt for key derivation should be stored together with the encrypted file, in a header or such.
Instead of creating your own ad-hoc file format for encrypted storage, have a look at the OpenPGP message format (as used by both PGP and GnuPG, and maybe other programs). It is specified in RFC 4880. You will likely not have to implement all of it, but grab the portions that you need for your application.
As an added bonus, the user can then use PGP/GPG (with the right options and the password/key) to decrypt the data, if your program should somehow cease to work.
Store them along with the ciphertext. You'll need to come up with a suitable file format in which to do it; a keyed archiver will make it easy.