-2

So normally if you do encrypt('a') twice in a row you'll get the same result. But sometimes (as is the case in SSH) this is not desirable. You want encrypt('a') || encrypt('a') == encrypt('aa'). What is this called?

PHP does it with mcrypt:

<?php 
$mcrypt = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($mcrypt, '@@@@@@@@', 'xxxxxxxx'); 
echo bin2hex(mcrypt_generic($mcrypt, 'dddddddd')); 
echo "\r\n"; 
echo bin2hex(mcrypt_generic($mcrypt, 'dddddddd'));

eg. you're encrypting dddddddd twice but getting a different result each time.

PHP does not do it with OpenSSL:

echo bin2hex(openssl_encrypt('dddddddd', 'des-cbc', '@@@@@@@@', OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, 'xxxxxxxx')); 
echo "\r\n"; 
echo bin2hex(openssl_encrypt('dddddddd', 'des-cbc', '@@@@@@@@', OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, 'xxxxxxxx'));

Given the API it makes since that OpenSSL wouldn't do it. It can certainly be emulated by changing the IV's but you'd have to do it manually.

Anyway, what is this called? Is it called progressive encryption? Continuous encryption?

yyyyyyy
  • 12,261
  • 4
  • 48
  • 68
neubert
  • 2,969
  • 1
  • 29
  • 58

3 Answers3

3

I don't think there is a dedicated name for this. If I had to find a word, it would probably be "stateful" or "with explicit state". What you observe is actually the usual case: The user initializes an encryption system with a key, resulting in some state of the system. Then, each time the user wishes to encrypt some data, he has to pass the current state along with it and the state gets updated by the encryption function. This way, one can encrypt messages that arrive in multiple pieces over time, resulting in greater flexibility (think live streaming!).

In your mcrypt example, the initialization is performed by mcrypt_generic_init, the state is stored in $mcrypt, and encryption is done by mcrypt_generic. In other languages, the state is encapsuled in "cipher objects", like those provided by, for instance, Python's Crypto.Cipher.* classes.

Then, there are special functions, like the OpenSSL example you provided, that are designed to encrypt just one single blob of data. They accept a key and a message as an argument and perform state initialization and encryption in one step, afterwards discarding the state and returning the ciphertext. The state is not exposed to the user, so he cannot continue encrypting more data. These functions exist solely for convenience, providing a simpler interface for the common case of encrypting one opaque message.

yyyyyyy
  • 12,261
  • 4
  • 48
  • 68
3

Your example is missing something: your two calls to the OpenSSL library are entirely entirely independent, but your calls to the mcrypt library reuse an existing handle. CBC has the property that identical plaintext blocks are exceedingly unlikely to encrypt to the same value due to chaining of the previous output into the next input.

Your OpenSSL calls cannot do this, because you are not preserving the CBC state between calls; two independent instances of the cipher are being initialized and used.

Additionally, even in independent calls, you almost never want encrypt('a') == encrypt('a'); this invalidates semantic security, and in many practical cryptosystems it allows an attacker to conduct a blockwise-adaptive chosen plaintext attack, which reveals the non-chosen plaintext contents. This is the fundamental reason why encryption modes use initialization vectors (which are non-secret, must be unique for the given key, and depending on the mode may need to be unpredictable): to ensure the encryption function has unique inputs even when the plaintext and key are the same.

Stephen Touset
  • 11,162
  • 1
  • 39
  • 53
1

In addition to yyyyyyy's answer, there is also probabilistic encryption, in which the encryption process incorporates some randomness. That allows many identical messages with the same key to be encrypted differently; it doesn't necessarily encrypt the same text differently in the same message (it might encrypt $a+a$ as $E(a)+E(a)$), but it does let you send the same plaintext multiple times with the same key without having it be the same ciphertext.

Probabilistic encryption is often done with stateful ciphers (by using a random and not-secret initialization vector to initialize the state of the cipher); it can also be done with hybrid crypto (a random key for the symmetric encryption), and certain algorithms are always probabilistic (e.g. ElGamal). Probabilistic encryption is different than just keeping track of state; you can do probabilistic encryption without keeping track of state (e.g. if you do hybrid encryption and your symmetric encryption is done in ECB mode, so within one message two identical blocks encrypt identically), and can keep track of state without doing probabilistic encryption (e.g. CBC mode with a fixed IV).

You mention that you'd have to change the IVs to get OpenSSL to do this; that's because you're supposed to change the IV every time you encrypt a new message. IVs are not secret, so you can just generate a new one for every message.

cpast
  • 3,652
  • 1
  • 16
  • 28