32 bit block cipher for .NET

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-12 09:53:32

问题


I need to encrypt 32 bit integers so they are represented by 32 bit integers. Is it possible to have a block cipher with 32 bit block size so the output is 32 bits?

I am currently using DES but the result is a 64 bit integer. I don't want to use XOR encryption as a last resort.


回答1:


Skip32, which is a based on the Skipjack algorithm, is the only 32-bit block cipher I am aware of: there is purportedly a Java implementation here.

For security, 64-bits is generally considered an absolute minimum block size.




回答2:


To make something like this work securely with common ciphers, you can operate a block cipher in a "stream" mode like OFB, CFB, or CTR. This means you need to have a suitable (unpredictable) initialization vector for each integer you are trying to encrypt, or (in CTR mode) have a well-defined message order.

I'm assuming that you want to decrypt the numbers later. If you are just trying to create a pseudo-random generator with a period of 232, there are other techniques you can try.




回答3:


you can write all integers into single byte array and encrypt them, another idea is to use 64 bit integers, casting them to 32bit when needed.




回答4:


If you don't care about security and just want a very small 32-bit block cipher, you can try this one. I use it to generate permutations of the integers in order to create families of hash functions, and I think it's fairly suitable for that purpose.

static uint syfer(uint key, uint data)
{
  uint R = (data^key) & 0xFFFF, L = (data>>16) ^ (((((R>>5)^(R<<2)) + ((R>>3)^(R<<4))) ^ ((R^0x79b9) + R)) & 0xFFFF);
  key = (key>>3) | (key<<29);
  R ^= ((((L>>5)^(L<<2)) + ((L>>3)^(L<<4))) ^ ((L^0xf372) + (L^key))) & 0xFFFF;
  return ((L ^ ((((R>>5)^(R<<2)) + ((R>>3)^(R<<4))) ^ ((R^0x6d2b) + (R^((key>>3)|(key<<29)))))) << 16) | R;
}

I can try to pick it apart, clean it up, and expand it into something more readable. (Hopefully I haven't made a mistake. It is way past my bedtime. :-)

static uint Cipher(uint key, uint data)
{
  uint L = data >> 16, R = data & 0xFFFF, S = 0x79b9;
  for(int round=0; round<24; round++)
  {
    uint F = L ^ (((((R>>5)^(R<<2)) + ((R>>3)^(R<<4))) ^ ((R^S) + (R^key))) & 0xFFFF);
    L   = R;
    R   = F;
    S  += 0x79b9;
    key = (key>>3) | (key<<29);
  }
  return (R<<16) | L;
}

You can increase the strength by increasing the number of rounds, but if you really want security (as far as you can get it with 32-bit block and key sizes), you'd be better off using skip32, as mentioned by GregS. (Note that the link he posted is broken, but this page has C source: http://metacpan.org/pod/Crypt::Skip32). This function has the benefit of being entirely self-contained, with no lookup tables or other dependencies, though.

[Edit: I just realized that I didn't post decryption code. But then you didn't say anything about decryption. ;-) I can write it up if anybody wants to see. It's really just the inverse of the above...]




回答5:


You could also consider Speck, a lightweight block cipher that comes in several sizes, including a version with a 32-bit block size and 64-bit key.




回答6:


A bit late, but a 32-bit block cipher is KATAN. Its performance in software is quite unacceptable though.

http://www.cs.technion.ac.il/~orrd/KATAN/




回答7:


I would use a modern block cipher (like AES, Twofish, Serpent) with CTR cipher mode. The answer from erickson mentioned something in that direction already. I try to elaborate here a bit on that.

While the cipher modes primary objective(*) is to protect you from statistical analysis of your cryptoblocks (for example preventing consecutive identical blocks producing identical cryptoblocks) you can also use CTR for transmitting a data chunk shorter than the cipher block size.

All of the block ciphers mentioned above have a block size of 128 bit. Just pad your message at the end with the extra 96 bits, for example with zeros (does not matter). Encode the message in CTR mode. You need to supply an IV block (initialization vector). You do not need to keep its value secret. However, for secure applications a new one should be randomly chosen for each transmission. Given your restriction to 32 bit codes I assume you have a low security scenario with transmittable data restricted to 32 bit, so you might stick with a fixed IV value. Just crop the result to 32 bit and transmit it.

For decoding, pad it again with 96 bits of any value, apply a regular decoding using CTR mode with above mentioned IV value and crop the value back to 32 bit. You are done!

In Python-like pseudocode (sorry, I am not into .net) that would be simply

# encode for plain_msg of length 32, key and iv
padded_plain_msg = plain_msg + [0]*96
padded_crypted_msg = encrypt(padded_plain_msg, key, mode=CTR, iv=iv)
crypted_msg = padded_crypted_msg[0:32]

# decode for crypted_msg of length 32, key and iv
padded_crypted_msg = crypted_msg + [0]*96
padded_decrypted_msg = encrypt(padded_crypted_msg, key, mode=CTR, iv=iv)
decrypted_msg = padded_decrypted_msg[0:32]

This is working because the CTR mode does not apply the cipher directly to the message but to a running counter (CTR: CounTeR) and xors the result with the message:

# CTR mode pseudocode on msg_blocks[0], msg_blocks[1], ..., msg_blocks[n-1] 
# to crypted_block[0], crypted_block[1], ..., crypted_block[n]
for i in range(n):  # i = 0, 1, ..., n-1:
    # one implementation variant--there are others counter sequences, e. g. 
    # appending half-block sized iv & a half-block chunk containing i
    crypted_block[i] = encrypt(iv+i, key) ^ msg_blocks[i]

Note that if you use a fixed IV value, you essentially have a 32 bit cipher (like you requested) and that is always attackable if the opponent gathers enough encrypted data. As James K Polk already pointed out you never want to use block ciphers of less than 64 bit if you care about security.

(*) Except for ECB (electronic code book) mode, which is a fancy way to say you apply the encoding on each block without any dependencies



来源:https://stackoverflow.com/questions/1971657/32-bit-block-cipher-for-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!