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.
Related
Here's the problem, a string has been passed through three separate encryptions in the following order: Original -> Base64 -> AES-256 -> Blowfish (Keyless) -> Final. Write a method that takes this triple encoded string mystery_string = "OXbVgH7UriGqmRZcqOXUOvJt8Q4JKn5MwD1XP8bg9yHwhssYAKfWE+AMpr25HruA" and fully unencrypts it to its original state.
I looked into different libraries/documentation for aes256 and blowfish but all of them required a key. The only one that did not require a key was Base64 (i.e. Base64.encode64('some string') ). Not really sure where to go from here.
Firstly, the only way to crack AES-256 and Blowfish without the key is by brute force enumeration of every possibly 32-byte combination that could be used as the key. In theory, this means it's not crackable in our lifetime. There may be some vulnerabilities you could exploit as you also have the plain text, but I doubt you would have that in a real-life situation.
Second, and most importantly, just going by that site, encode-decode.comhttps://encode-decode.com/, you don't actually have enough information to decode the string even if you did know the password.
The various modes of operation for the AES256 cipher function requires either a 32-byte (or sometimes a 64-byte) key. The secret that you used (you may have just left it blank) needs to be converted into a 32-byte encryption key. This is done using a hashing algorithm, but we don't know which one is used. Hopefully, the site used a key derivation function, which provides several security benefits. However, key derivation functions require multiple parameters, and we would need to know what parameters to enter along with our secret to get the right encryption key.
Finally, we don't know if the secret is being concatenated with a salt before being hashed. Without knowing if a salt is used and what the salt is, we cannot determine the correct 32-byte key used to encrypt the plain text.
In summary, the answer to your question is: No, there is not a quick way to decrypt that string without knowing the key.
However, encryption is an awesome topic to learn.
I'd encourage you to look over the ruby docs for the OpenSSL library. They're actually quite good (besides the don'ts I mention below).
The PBKDF2 Password-based Encryption function is one of the key derivation functions I was referring to.
When encrypting with AES, you will most likely want to use AES-256-GCM which is authenticated encryption.
A couple of don'ts:
Don't use ciphers at random... understand their strengths and weaknesses
Don't use AES-128-EBC - explination
Another good encryption library is rb-NaCl.
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 problem is most easily understood by reading my attached Gist: https://gist.github.com/KazW/e77e5c7603d7700d86c1
I have a simple encrypt/decrypt function in Ruby that works. Every time the encryption function is run, a new initialization vector is created using OpenSSL::Random.random_bytes(12). When I try to do the same steps in Elixir, using :crypto.strong_rand_bytes(12), it generates an IV that can be used for encryption, but causes decryption to fail.
Stranger still, if I use an IV generated in Ruby, and use it to Encrypt in Elixir. When passing the ciphertext to decrypt in Elixir, the decryption function returns the plaintext without error. I've researched the algorithm in use, the IV is supposed to be random bytes, the important factor is the number of bytes in it (12).
My initial thought is that perhaps I'm calling the wrong OpenSSL method to generate the IV. However, I wasn't able to find any information as to what the correct method would be.
The issue here is that you are using String functions to read the data, which only works with Unicode, and UTF8 characters are variable-width. You should use pattern matching instead, which uses single-byte width.
https://gist.github.com/asonge/4f035a38a9b31339d8f5
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.