Garbage chars with AES encryption in CBC mode with openssl and dmsetup - linux

I got a strange problem.
I filled a text file with the letter 'A' and made it 4096 bytes long.
Then a encrypted it with openssl on linux:
KEY="2D242B65C517B72F8D1DAA8278CA5A2ED5D8A95BCF82BFD3778212218726335F"
openssl enc -nosalt -iv 0 -K $KEY -aes-256-cbc -in $PLAINIMAGENAME -out $CRYPTIMAGENAME
(No salt, no IV)
Then a tried to create a device-mapper loopback device with dm-crypt:
losetup /dev/loop0 $CRYPTIMAGENAME
sudo dmsetup create cryptotest --table "0 4096 crypt aes-cbc-null $KEY 0 /dev/loop0 0"
When I try to read from /dev/mapper/cryptotest I get my A's, but every 512 bytes (block size?) there are 16 bytes of garbage. How is this possible?
When I use the ECB-mode (where every block is encrypted in the same way) everything works fine.
By the way I don't want to use LUKS for loopback encryption, I need a headerless AES stream which can be created by openssl or aespipe.

I found the solution to the problem:
The device-mapper needs to start a new CBC every sector (512 bytes == 32 AES blocks) to be able to have random-access to the sectors without having to decrypt everything before that. Therefore I have to concatenate aes-128-cbc encryption streams with a length of 512.
Of course an IV of zeros is not good at all. I use aes-128-cbc-essiv:sha256 now. The ESSIV is calculated with a hash (sha256) of the encryption key and the sector number, so no sector has the same encrypted data.
Further information can be found here: http://www.penzin.net/dmcrypt/

Related

How does RSA Passphrase Encryption work under the hood?

So in the .ssh directory, there is a file named "id_rsa" which is the private key file.
It contains the encrypted private key, and and encryption algorithm (AES128-CBC) as well as the Initialization Vector.
I understand that it gets decrypted automatically when you enter your passphrase and I understand that the decryption algorithm takes in the encrypted private key, and the passphrase (as the key), as well as the IV (I am given this already).
I just want to know how the passphrase is padded? Cause AES 128 takes in a key size of 128 bits, and a passphrase is usually a lot smaller than that.
I am trying to manually decrypt my private key (for learning purposes) . The only missing thing I have, is how I should pad my "passphrase" so I can pass it in the encryption algorithm.
Basically, to sum it all up, how is a passphrase which is a string converted to a 128 bit (16 byte) key?

What is the equivalent cipher to bouncycastle's PaddedBufferedBlockCipher with AESEngine and PKCS7 padding?

I want to decrypt AES-256 encrypted string using nodejs. I am using crypto module for that.
The string is encrypted using Bouncy castle java library. In Java the cipher is intialsed using:
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new AESEngine(), new PKCS7Padding());
crypto module of nodejs uses openssl's list of ciphers for intialising it, like:
var decipher = crypto.createDecipher('aes-256-cbc',key);
Which algorithm should I use?
Here is the list of algorithms to choose from:
-bash-4.1$ openssl list-cipher-algorithms|grep AES-256
AES-256-CBC
AES-256-CFB
AES-256-CFB1
AES-256-CFB8
AES-256-CTR
AES-256-ECB
AES-256-OFB
AES-256-XTS
AES256 => AES-256-CBC
aes256 => AES-256-CBC
If you encrypt something with a block cipher, you need
the block cipher which can take a single block of input and mangle it into a single block of output (for AES the block size is 16 bytes),
the mode of operation which enables you to encrypt more than one block in a structured fashion
the padding which enables you to encrypt something that is not exactly as long as a multiple of the block size.
The PaddedBufferedBlockCipher that you've shown only has two of them. The mode of operation is implied to be ECB mode, because it simply consists of applying the block cipher to each block separately.
You'll get the same behavior in node.js with:
var decipher = crypto.createDecipheriv('aes-xxx-ecb', key, '');
Exchange the xxx for the size of your key in bits. Valid sizes are 128 bit, 192 bit and 256 bit. Everything else will not work. Also, make sure that you get the encoding of your key right.
In case you're wondering why createDecipheriv is used here instead of createDecipher, I suggest that you carefully compare the documentation to both of those functions. createDecipher expects a password and not a key.
Other considerations:
Never use ECB mode. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like CBC or CTR. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.
Decrypt the data with AES-256-ECB (I don't see any CBC or other modes.).
Call decipher.setAutoPadding(true) for using PKCS padding.

How do I tell if OpenPGP encryption is symmetric or asymmetric?

Is there a way to tell if things encrypted via the GNU Privacy Guard are symmetric or asymmetric (without decrypting them or already knowing to start with)? How?
Anyway (for those who want to know what I'm doing), I used Python 3.x to program a GUI-based IDE of sorts that can open symmetrically encrypted files (and save them, too). It can open asymmetrically encrypted files (enter the passphrase to use your secret key instead of the passphrase to decrypt a symmetrically encrypted file). However, it doesn't know they're asymmetric and will overwrite them with symmetrically encrypted files if saved. It would be nice to be able to save them asymmetrically, too. My editor uses the gpg command-line program on Linux (no gpg libraries or anything like that).
I could have a checkbox on the password prompt for asymmetric encryption, but I'd rather not make it so it has to be a manual thing for the user.
For my own personal files, I could add some kind of marker to the saved files to distinguish, but I want it to be able to open them correctly even if they weren't created in my IDE.
I know there's a question with a similar title, but the question asked in the body is fundamentally different.
OpenPGP is a hybrid cryptosystem, which means messages (or files) are always encrypted symmetrically using a so-called session key. The session key again is encrypted using asymmetric encryption (using a public key) or symmetric encryption again (using a string to key function).
This has technical reasons (asymmetric cryptography is very slow for large amounts of data), but also practical ones: by encrypting the small session key multiple times (once for each recipient), you can also have multiple recipients with different keys and even mix asymmetric (public key) and symmetric (password based) encryption in a single OpenPGP message.
Each of those encrypted copies of the session key form an OpenPGP packet, either a packet with tag 1 (Public-Key Encrypted Session Key Packet) or a packet with tag 3 (Symmetric-Key Encrypted Session Key Packet). Those packets in an OpenPGP message can be easily decomposed using pgpdump. An example using GnuPG to create an OpenPGP message encrypting for both my own key and symmetrically for the passphrase foo:
$ echo foo | gpg --recipient a4ff2279 --symmetric --passphrase foo --encrypt | pgpdump
Old: Public-Key Encrypted Session Key Packet(tag 1)(524 bytes)
New version(3)
Key ID - 0xCC73B287A4388025
Pub alg - RSA Encrypt or Sign(pub 1)
RSA m^e mod n(4096 bits) - ...
-> m = sym alg(1 byte) + checksum(2 bytes) + PKCS-1 block type 02
Old: Symmetric-Key Encrypted Session Key Packet(tag 3)(46 bytes)
New version(4)
Sym alg - AES with 128-bit key(sym 7)
Iterated and salted string-to-key(s2k 3):
Hash alg - SHA512(hash 10)
Salt - 0c a6 e6 1d d2 f4 9a 50
Count - 102400(coded count 105)
Encrypted session key
-> sym alg(1 bytes) + session key
New: Symmetrically Encrypted and MDC Packet(tag 18)(63 bytes)
Ver 1
Encrypted data [sym alg is specified in sym-key encrypted session key]
(plain text + MDC SHA1(20 bytes))
Each of the first two packets forms a key to open the encrypted string in the Symmetrically Encrypted and MDC Packet.
This also already explains how to analyze how a message was encrypted: look through the packets, looking for either tag 1 or 3 packets, indicating asymmetric or symmetric encryption (and be aware both might exist). You seem to be very lucky, and the Python GnuPG module already brings a ListPackets class, so you neither have to interface pgpdump nor write your own OpenPGP parser.
Since you are using linux commands, I think you can try with the "file" utility to check the header and tell if the encryption is symmetric or asymmetric.
The output would be something like this (Tested in Ubuntu 14.04):
Command: file symm_encrypted.txt.gpg
Output: GPG symmetrically encrypted data (CAST5 cipher)
Command: file asymm_encrypted.txt.gpg
Output: GPG encrypted data

An RNG faster than /dev/random but cryptographically useful?

I've started some work of which requires some quality random bytes, such as 32 at a time for an initialising vector for certain cryptographic applications. My issue is, this may be called upon multiple times simultaneously and I cannot afford the block /dev/random issues to wait for more collection of entropy.
I could use it to seed other algorithms, for example what /dev/urandom may do - however I do not trust what I cannot understand, I do not have any readily available resource on its method nor do I know if it remains the same between many kernel versions, I prefer a well defined method of some sort.
Are you aware of any methods you can think of over standard PRNGs that would be suited enough to use for (simultaneous) key generation and alike?
Would certain ciphers such as RC4 with a large seed be sufficient to generate random output? (I've seen a /dev/frandom implementation that uses this, however am not entirely sure of it.)
If it means anything, I am on a headless Debian server, reason of lack of entropy gathering.
The response is simple: use /dev/urandom, not /dev/random. /dev/urandom is cryptographically secure, and will not block. The "superiority" of /dev/random over /dev/urandom exist only in a specific theoretical setting which makes no sense if the random bytes are to be used with just about any "normal" cryptographic algorithm, such as encryption or signatures.
See this for more details.
(Trust me, I am a cryptographer.)
Consider using a hardware random number generator. For example, the entropy key or Whirlygig. Using /dev/urandom instead will avoid blocking but may (depending on your level of paranoia) degrade security (you'll output more random bits than you have input entropy, so in theory the output is predictable - this isn't a problem if you're just using it for IVs however)
On a modern CPU with AES hardware acceleration, you can easily reach more than 1 GiB/s of random data by encrypting a string of zeros using a random password (from /dev/urandom), as shown by another answer on serverfault. Note that the random password is passed as a pipe, so that it doesn't show up in the process list.
On my machine, this approach is roughly 100 times faster than /dev/urandom:
$ openssl enc -aes-256-ctr -pass file:<(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64) -nosalt < /dev/zero | pv > /dev/null
11.2GiB 0:00:09 [1.23GiB/s] [ <=> ]
$
$ # Let's look at /dev/urandom for comparison:
$ pv < /dev/urandom > /dev/null
48MiB 0:00:04 [12.4MiB/s] [ <=> ]
If you put this in a shell script, you can easily pipe it into other processes:
$ cat ~/.bin/fast_random
#!/bin/bash
openssl enc -aes-256-ctr \
-pass file:<(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64) \
-nosalt < /dev/zero

m2crypto aes-256-cbc not working against encoded openssl files

$ echo 'this is text' > text.1
$ openssl enc -aes-256-cbc -a -k "thisisapassword" -in text.1 -out text.enc
$ openssl enc -d -aes-256-cbc -a -k "thisisapassword" -in text.enc -out text.2
$ cat text.2
this is text
I can do this with openssl. Now, how do I do the same in m2crypto. Documentation is lacking this. I looked at the snv test cases, still nothing there. I found one sample, http://passingcuriosity.com/2009/aes-encryption-in-python-with-m2crypto/ (changed to aes_256_cbc), and it will encrypted/descrypt it's own strings, but it cannot decrypt anything made with openssl, and anything it encrypts isn't decryptable from openssl.
I need to be able enc/dec with aes-256-cbc as have many files already encrypted with this and we have many other systems in place that also handle the aes-256-cbc output just fine.
We use password phrases only, with no IV. So setting the IV to \0 * 16 makes sense, but I'm not sure if this is also part of the problem.
Anyone have any working samples of doing AES 256 that is compatible with m2crypto?
I will also be trying some additional libraries and seeing if they work any better.
Part of the problem is that the openssl created file contains 16 bytes of prepended salt information Salted__xxxxxxxx. So, these must be extracted first, then decryption may occur. The next problem is to take original password, sprinkle in the salt, and take the generated key from that and make the key/iv pair for decryption. I have been able to make the first round of they key in hash, but being 256 bit, it needs two rounds to be successful. The problem is creating the second round of hash.
It should also be mentioned that we are locked into python 2.4 so some of the future key routines that are introduced do not work for us.

Resources