I am using Guardian to realize JWT Authentication with an Elixir / Phoenix app. I'm using the HS512 algorithm. And I need a key for that. Are there any conditions for this key except that it has to be 512 bits or longer? It can be any arbitrary string, right?
openssl rand -base64 172 | tr -d '\n'
OpenSSL generates a secret of 129 bytes ((172 * 6) / 8). 129 bytes is good for HS512 (see https://github.com/ueberauth/guardian/issues/152).
tr removes newlines.
You need to run this command on a Linux machine with OpenSSL library installed:
echo -n "somevalue" | openssl sha512 -hmac "somekey"
The output of this command is the HS512 (HMAC SHA512) which you can use as the signing key with any JWT library.
The signing key is a byte array of any value or length you wish. Most JWT libraries allow you to use any string as key, which is converted to byte array.
To generate a secure 20 byte key, bs64 encoded
dd if=/dev/random bs=20 count=1 status=none | base64
In case anyone visits this now: Guardian added a mix task for that.
mix guardian.gen.secret
https://hexdocs.pm/guardian/Mix.Tasks.Guardian.Gen.Secret.html#content
I'm pretty confident that any arbitrary string will work. Best practice would be to store that string in an environment variable and then have your app pull from that.
Related
I downloaded the openssl-1.0.2l.tar.gz source package from https://www.openssl.org/source/ and made a fresh x64 build for Windows. I use the openssl application to encrypt a file using the following command:
openssl enc -aes-128-cbc -a -salt -in data.txt -kfile key.txt -out encrypted.txt -p
Now, I would like to consume the encrypted file in a .NET application (written in C#). I read the encrypted file (which is encoded using Base64, because of the -a switch), decode it, and extract the first 16 bytes in order to get the salt that was generated by OpenSSL... this works fine so far; the salt is prefixed with Salted__, the following 8 bytes are the actual salt value.
What I have learned so far is that OpenSSL reads the first line of the given key file and uses that string for the passphrase. The actual key and initialization vector gets derived from the passphase, the salt and some hashing, which is not officially documented.
The -p switch gave me the key and initialization vector that is used for the encryption, but I would like to know, how I can reproduce that data from the known passphrase and the salt... Everything I have tried gives me key and vector data that is different from what the openssl application gave me.
Of course, I already found similar questions (and answers) at stackoverflow and crypto.stackexchange, but none of the solutions seem to work, or are related to aes-256-cbc... not sure, if that makes a difference?
What needs to be done to properly derive the key and initialization vector?
It's documented here or here, but you have to know what to look for. The function is called EVP_BytesToKey and uses a hash function to stretch the salt and password into a key and IV.
Note that OpenSSL switched from MD5 to SHA-256 in version 1.1.0 (source). The iteration count is 1 and the output size depends on the chosen key size and block size.
I'm still new to encryption in general, and I understand why an IV is necessary, but isn't the IV embedded in the encrypted data? Thus, shouldn't any decryption implementation first extract the IV from the data rather than needing to have it supplied?
The reason I assume the IV is embedded in the data is because certain libraries/tools do not require that it be supplied, for instance CryptoJS for JavaScript: CryptoJS.AES.decrypt("U2FsdGVkX1/l3HWODO9GX23rvF0KHmDR6z8XTpYYpe8=", "password").toString(CryptoJS.enc.Utf8));
and openssl: echo "U2FsdGVkX1++pGg+oWqZbIjccV1NiV2pc1QrQtw0wp4=" | openssl aes-256-cbc -d -a -pass pass:password
and really any actual app that does AES encryption, like TrueCrypt.
Libraries that seem to require the IV:
mcrypt for PHP: http://us2.php.net/manual/en/function.mcrypt-decrypt.php
SymmetricAlgorithm in .Net: http://msdn.microsoft.com/en-us/library/79w421xb%28v=vs.110%29.aspx
am i getting something confused?
No, the IV may be derived as well. The only reason to include the IV with the ciphertext is when the key is reused for encryption and when the IV cannot be derived. It is common but not standardized or required to prefix it if it is present. But that's when you need the IV, so it's the de-facto standard none-the-less.
In your OpenSSL example a random salt is used to generate a key from a password. In that case the salt is different for each encrypt, so the key is random as well. In that case an randomized IV is not needed, although it can (and will be for OpenSSL) derived from the salt and password as well.
Other protocols contain a counter, and in that case a single block encrypt over the counter can be used to create an IV for CBC mode encryption. As long as the counter stays the same at sender/receiver, there is no need to send the IV.
And there are plenty cryptograhic implementations that get it wrong and don't use a random IV for CBC mode. PHP mcrypt_encrypt is special in the sense that it even requires an IV for ECB mode, which is then thouroughly ignored as ECB does not use an IV anywhere in the algorithm.
I am working with jcls on mainframe with the program pkzip and pkunzip for creating and reading zip files.
I need some information about the AES encryption of creating password protected zip files. I want to know what is the default / standard AES encryption type (128 / 192/ 256 bits) of pkzip?
I know you can set the Parameter in the jcl file but if you won't set it, what will be the default value?
I didn't find any Information in the documentation.
https://www.pkware.com/documents/manuals/PKMU-V5R5000.pdf
Thank you
Seems to me you can specify what pkzip uses: -AES128 | -AES192 | -AES256 are clearly indicated in the document you point to, and CBC mode is specified. And the decryption will detect which one was used from the archive - again as documented.
Now that i am thinking about it, it seems unusual that i dont know.
Is there an app that allows me to encypt data with std in/out/error? perhaps something like
appname -c AES -k MyTextKey (or -kh for a key made from hex data) -o stdout -i stdin
I never bothered learning how to use one outside of .NET and it would be annoying to do it for each language. Signing would be good too
appname -s salt_text -in file.blah -o key.sig
On windows but i'd like a linux solution as well.
-edit- gpg does not look like a solution. I looked but cant see how to encrypt something with cipher using a password and not use public/private keys which seem to be the only way it can encrypt.
You can use openssl for this.
On most linux flavors you can use gpg.
GPG website
Here's an example in .net of the GnuPG calls wrapped in managed .net code. The encryption / decryption occurs by writing / reading to the console process using streamreader / streamwriter calls.
http://www.codeproject.com/KB/security/gnupgdotnet.aspx
Is it possible to encrypt data, such that it can be decrypted with several different keys?
Example:
I've encrypted data with key1, but I want to be able to decrypt with keys 2, 3, and 4.
Is this possible?
GnuPG does multi-key encryption in standard.
The following command will encrypt doc.txt using the public key for Alice and the public key for Bob. Alice can decrypt using her private key. Bob can also decrypt using his private key.
gpg --encrypt --recipient alice#example.com \
--recipient bob#example.com doc.txt
This feature is detailed in the user guide section entitled "Encrypting and decrypting documents"
Yes it's possible
Yes encryption for multiple recipients is possible. Also it seems logical when you think that you might want to be able to read what you've sent to someone and to do so you need to be in the recipients list.
Command line
Here is how to do it through gpg command line (as described in David Segonds' answer):
gpg --encrypt \
--recipient alice#example.com \
--recipient bob#example.com \
clear-message.txt
GUI client
Your GUI must provide a way to encrypt for several people
Mechanism
There is a question on Information Security, GPG File size with multiple recipients?, that explain the encryption mechanism:
GPG encrypts the file once with a symmetric key, then places a header
identifying the target keypair and an encrypted version of the
symmetric key.
[...] When encrypted to multiple recipients, this
header is placed multiple times providing a uniquely encrypted version
of the same symmetric key for each recipient.
GnuPG and PGP clients in general usually encrypt the actual data with a symmetric key called a "session key". The session key is then encrypted with each "recipient key" (i.e. the ones you specify with -r/--recipient). This is sometimes referred to as a hybrid cipher. Right now, I believe GnuPG by default uses an 256 bit session keys and AES to encrypt the plaintext data to that AES-256 session key, and your recipient keys are your RSA/DSA/ECDSA/etc. assymetric key in this case.
One reason for doing it this way is that symmetric cryptographic algorithms like AES are generally a lot faster than asymmetric ones like RSA. GnuPG thus only has to encrypt ~256 bits (the session key) with RSA, and can use AES to encrypt the data (as large as you want it to be!) with that session key. Intel machines even have a built in instruction, AES-NI, to do some steps of the algorithm in hardware, which makes GnuPG extra snappy at encrypting/decrypting data.
Another reason for doing it this way is that it allows PGP-encrypted documents to be encrypted to multiple parties without having to double the size of the document. Notice that when you specify multiple recipients for an encrypted document (e.g. gpg -ea -r Alice -r Bob -o ciphertext.asc), the encrypted document that gets stored (ciphertext.asc) is not 2x as large as if you had just encrypted it to Alice.
See also the --show-session-key parameter in the gpg man page to be able to decrypt just the session key, for example to allow a third party to decrypt a document that is encrypted to you without having to transfer to them your private key or the plaintext data.
Yes, it's possible. Google "multiparty encryption" for a start.
AFAIK, there are no drop 'em in and use 'em packages for it though.
-- MarkusQ
P.S. For a sketch of how it could be done, consider this. The encrypted message consists of:
the payload, encrypted with a one-time pad
the one time pad, encrypted with key1
the one time pad, encrypted with key2
...
the one time pad, encrypted with keyN
The recipient who hold key i just decrypts their copy of the pad with their key, and then decrypts the payload.
However, this is just a proof that it could be done and would suck as an actual implementation. If at all possible, you should avoid rolling your own encryption. If you don't understand why, you should definitely avoid rolling your own encryption.
-----Edit ------------
If I'm wrong and the Gnu tools do that, use them. But I can't seem to find any information on how to do it.
Multiple (more than two) key RSA is maybe like this - well i'm not a mathematician, so this algorithm is not necessarily secure, i just want to give an idea with it.
m=p*q*r; p,q,r are big prime numbers
fi(m)=(p-1)(q-1)(r-1)
d==(e1*e2*e3*...*ei)^(-1) (mod fi(m)); e1...ei are arbitrary numbers, d is calculated to fulfill the equation
y1==x^e1 (mod m)
y2==y1^e2 (mod m)
y3==y2^e3 (mod m)
...
x==yi^d (mod m)
This algorithm could be used for example to increase the speed of The Onion Router.