openssl_cipher_iv_length workaround - encryption

I need to implement the openssl_cipher_iv_length() functionality on PHP version 5.3 where this function is not supported.
Would anybody be able to explain a way in which I can do this using PHP 5.3 friendly functionality only?

(Assuming you are always using AES as written in the comment)
For most of common AES cipher modes (CBC,CFB,ECB,OFB) the IV length should be 128 bits = 16 bytes, regardless of the key length (the 128/192/256 number in the name of cipher method).
As the openssl_cipher_iv_length() function returns the IV length in bytes, your implementation should return a constant value of 16.
Good luck!

Related

Extending short key for AES256 (SNMPv3)

I am currently working on security of a switch that runs SNMPv3.
I am expected to code it in such a way, that any SHA (1 - 2-512) is compatible with any AES (128 - 256C).
Everything, like the algorithms alone, works pretty well. The problem is, that its been estabilished, that we are going to use SHA for key generation for both authentification and encryption.
When I want to use, let's say, SHA512 with AES256, there's no problem, since SHA has output of 64B and I need just 32B for key for AES256.
But when I want to use SHA1 with AES256, SHA1 produces only 20B, which is insufficient for the key.
I've searched the internet through and through and I found out, that it's common to use this combination (snmpget, openssl), but I havent found a single word about how are you supposed to prolong the key.
How can I extend the key from 20B to 32B so it works?
P. S.: Yes, I know SHA isn't KDF, yes, I know it's not that common to use this combination, but this is just how it is in my job assignment.
Here is a page discussing your exact question. In short, there is no standard way to do this (as you have already discovered), however, Cisco has adopted the approach outlined in section 2.1 of this document:
Chaining is described as follows. First, run the password-to-key algorithm with inputs of the passphrase and engineID as described in the USM document. This will output as many key bits as the hash algorithm used to implement the password-to-key algorithm. Secondly, run the password-to-key algorithm again with the previous output (instead of the passphrase) and the same engineID as inputs. Repeat this process as many times as necessary in order to generate the minimum number of key bits for the chosen privacy protocol. The outputs of each execution are concatenated into a single string of key bits.
When this process results in more key bits than are necessary, only the most significant bits of the string should be used.
For example, if password-to-key implemented with SHA creates a 40-octet string string for use as key bits, only the first 32 octets will be used for usm3DESEDEPrivProtocol.

Is it possible to tell which hash algorithm generated these strings?

I have pairs of email addresses and hashes, can you tell what's being used to create them?
aaaaaaa#aaaaa.com
BeRs114JrR0sBpueyEmnOWZfnLuigYTA
and
aaaaaaaaaaaaa.bbbbbbbbbbbb#cccccccccccc.com
4KoujQHr3N2wHWBLQBy%2b26t8GgVRTqSEmKduST9BqPYV6wBZF4IfebJS%2fxYVvIvR
and
r.r#a.com
819kwGAcTsMw3DndEVzu%2fA%3d%3d
First, the obvious even if you know nothing about cryptography: the percent signs are URL encoding; decoding that gives
BeRs114JrR0sBpueyEmnOWZfnLuigYTA
4KoujQHr3N2wHWBLQBy+26t8GgVRTqSEmKduST9BqPYV6wBZF4IfebJS/xYVvIvR
819kwGAcTsMw3DndEVzu/A==
And that in turn is base64. The lengths of the encodings wrt the length of the original strings are
plaintext encoding
17 24
43 48
10 16
More samples would give more confidence, but it's fairly clear that the encoding pads the plaintext to a multiple of 8 bytes. That suggest a block cipher (it can't be a hash since a hash would be fixed-size). The de facto standard block algorithm is AES which uses 16-byte blocks; 24 is not a multiple of 16 so that's out. The most common block algorithm with a block size of 8 (which fits the data) is DES; 3DES or blowfish or something even rarer is also a possibility but DES is what I'd put my money on.
Since it's a cipher, there must be a key somewhere. It might be in a configuration file, or hard-coded in the source code. If all you have is the binary, you should be able to locate it with the help of a debugger. With DES, you could find the key by brute force (because a key is only 56 bits and that's doable by renting a bit of CPU time on Amazon) but finding it in the program would be easier.
If you want to reproduce the algorithm then you'll also need to figure out the mode of operation. Here one clue is that the encoding is never more than 7 bytes longer than the plaintext, so there's no room for an initialization vector. If the developers who made that software did a horrible job they might have used ECB. If they made a slightly less horrible job they might have used CBC or (much less likely) some other mode with a constant IV. If they did an again slightly less horrible job then the IV may be derived from some other characteristic of the account. You can refine the analysis by testing some patterns:
If the encoding of abcdefghabcdefgh#example.com (starting with two identical 8-byte blocks) starts with two identical 8-byte blocks, it's ECB.
If the encoding of abcdefgh1#example.com and abcdefgh2#example.com (differing at the 9th character) have identical first blocks, it's CBC (probably) with a constant IV.
Another thing you'll need to figure out is the padding mode. There are a few common ones. That's a bit harder to figure out as a black box except with ECB.
There are some tools online, and also some open source projects. For example:
https://code.google.com/archive/p/hash-identifier/
http://www.insidepro.com/

Identification of padding scheme in RSA

How to determine the padding scheme used in a RSA encrypted message?
The best way is probably to perform PKCS#1 v1.5 or OAEP decryption and see if you hit gold. The unpadding will fail if the wrong algorithm is chosen.
It is possible to raw decipher and then look at the resulting scheme by representing the padded message as hexadecimals. If the resulting octet string (byte array) starts with 0002 then it's likely PKCS#1 v1.5 padding. If it starts with 00 and then a random looking byte it's probably OAEP. As you can see, this is just a heuristic, not a full fledged algorithm. Note that OAEP's MFG1 can be parameterized with a hash function, but usually SHA-1 is used.
RSA-KEM is not used much, but as it results in a completely random key seed (possibly excluding the first bit), there is no way to test for RSA-KEM other than to expect RSA-KEM if the ciphertext and private key can be verified to be correct and the value doesn't match one of the other schemes / lacks structure.
The protocol should define which algorithm is used. Leaving the choice of algorithm to the decryption routine opens up your implementation to attacks. The security proof of ciphers doesn't allow for other algorithms to be chosen.
So you can use above to analyze the protocol, but please do not use it in your implementation to choose between algorithms in the field.

What is the encryption strength if I don't know the encryption method and parameters?

If I use different encryption methods but provide no indication in the ciphertext output of which method I use (for example, attaching an unencrypted header to the ciphertext) does that make the ciphertext harder to decrypt than just the difficulty implied by, for example, the keylength? The lack of information as to what encryption protocol and parameters to use should add difficulty by requiring a potential decrypter to try some or all the various encryption methods and parameters.
Well, in general you should not rely on information in the algorithm / protocol itself. Such information is generic for any key you use, so you should consider it public knowledge. OK, so that's that out of the way.
Now say you use 16 methods and you somehow have created a protocol that keeps the used encryption method confidential (let's say by encrypting a single block half filled with random and a magic, decrypting blocks at the receiver until you find the correct one). Now if you would want to brute force the key used you would need 16 more tries. In other words, you just have increased the key length with 4 bits, as 2 ^ 4 = 16. So say you would have AES-256 equivalent ciphers. You would now have equivalent encryption of 256 + 4 = 260 bits. That hardly registers, especially since AES-256 is already considered safe against attacks using a quantum computer.
Now those 4 bits comes at a very high price. A highly complex protocol using multiple ciphers. Each of these ciphers have their weaknesses. None of them will have received as much scrutiny as AES, and if one breaks you are in trouble (at least for 1 out of 16 encrypted messages). Speeds will differ, parameters and block sizes will differ, platforms may not support them all...
All in all, just use AES-256 if you are not willing to accept AES-128. If you must, encrypt things twice using AES and SERPENT. Adding an authentication tag over IV & ciphertext probably makes much more of a difference though. See this answer by Thomas over at the security site.
Try GCM or EAX mode of operation. Much more useful.

encryption of a single character

What is the minimum number of bits needed to represent a single character of encrypted text.
eg, if I wanted to encrypt the letter 'a', how many bits would I require. (assume there are many singly encrypted characters using the same key.)
Am I right in thinking that it would be the size of the key. eg 256 bits?
Though the question is somewhat fuzzy, first of all it would depend on whether you use a stream cipher or a block cipher.
For the stream cipher, you would get the same number of bits out that you put in - so the binary logarithm of your input alphabet size would make sense. The block cipher requires input blocks of a fixed size, so you might pad your 'a' with zeroes and encrypt that, effectively having the block size as a minimum, like you already proposed.
I'm afraid all the answers you've had so far are quite wrong! It seems I can't reply to them, but do ask if you need more information on why they are wrong. Here is the correct answer:
About 80 bits.
You need a few bits for the "nonce" (sometimes called the IV). When you encrypt, you combine key, plaintext and nonce to produce the ciphertext, and you must never use the same nonce twice. So how big the nonce needs to be depends on how often you plan on using the same key; if you won't be using the key more than 256 times, you can use an 8 bit nonce. Note that it's only the encrypting side that needs to ensure it doesn't use a nonce twice; the decrypting side only needs to care if it cares about preventing replay attacks.
You need 8 bits for the payload, since that's how many bits of plaintext you have.
Finally, you need about 64 bits for the authentication tag. At this length, an attacker has to try on average 2^63 bogus messages minimum before they get one accepted by the remote end. Do not think that you can do without the authentication tag; this is essential for the security of the whole mode.
Put these together using AES in a chaining mode such as EAX or GCM, and you get 80 bits of ciphertext.
The key size isn't a consideration.
You can have the same number of bits as the plaintext if you use a one-time pad.
This is hard to answer. You should definitely first read up on some fundamentals. You can 'encrypt' an 'a' with a single bit (Huffman encoding-style), and of course you could use more bits too. A number like 256 bits without any context is meaningless.
Here's something to get you started:
Information Theory -- esp. check out Shannon's seminal paper
One Time Pad -- infamous secure, but impractical, encryption scheme
Huffman encoding -- not encryption, but demonstrates the above point

Resources