0

I need to find a way to (preferably asymmetrically)[1] encrypt/decrypt a single Int32, with the resulting encrypted value containing only valid characters[2] and being under eleven characters in length.

How would I go about doing this?

[1] Given the answers so far, symmetric encryption is fine

[2] alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()

Daniel Coffman
  • 1,997
  • 3
  • 26
  • 34

5 Answers5

2

You cannot use asymmetric encryption, like RSA, and get something small. The encrypted value will be the size (in bytes) of the modulus, e.g. 128 bytes for 1024bits. IIRC .NET won't allow you to use a key smaller than 384bits (48 bytes) which is still too large and not very secure [1].

You better use a symmetric algorithm, block sizes between 64 and 256 bits, and then use base64 on the result (that should give you 11 characters for 64 bits).

[1] In any case remember than guessing an integer is, at the maximum, a 2^32 problem ;-)

poupou
  • 43,413
  • 6
  • 77
  • 174
  • @andrew then the charset needs to be grown a bit. 85 different characters would be enough with a 10 character limit. – CodesInChaos Aug 09 '11 at 19:52
  • heh, I got suck with the number 11 - but forgot the 'under' part ;-) but honestly my main point was encrypting 32 bits won't ever be hard to break, whatever the crypto being used :-) – poupou Aug 09 '11 at 20:00
  • depending on the usage padding it removes some weaknesses inherent to the limited plain text space. – CodesInChaos Aug 09 '11 at 20:06
  • There's a ton of stuff we can pad with if necessary. The critical part is that is contains at least one Int32 and that the length of the cyphertext is very short. – Daniel Coffman Aug 09 '11 at 20:36
  • Padding can help, not a ton but to a maximum of 64 bits (to get the short strings), in some cases. However it won't help against guessing the value (it's still 32 bits) if/once anyone guess (or find out) what's being encrypted (an int32). – poupou Aug 09 '11 at 21:10
1

as another answer says, an asymmetric solution is difficult and your best, standard solution is to use a symmetric cipher with a short block size. your restriction to ten characters implies 60 bits with base 64, but you could use a custom encoding to get 64 bits (with a block cipher you need to send an exact number of blocks).

if you use a 64 bit block size you will have to fix the IV. in other words, if you send the same number twice, it will be encoded the same way both times [not true! - see neat idea in comments below]. but with a 32 bit block cipher you could use a random IV (padding to hide repeated values). it looks like skip32 would be a good choice - see Which "good" block encryption algorithm has the shortest output?

another, ad-hoc idea, that i just pulled out my ass, and which may therefore be insecure is to split your message into two: 32bits and the rest. fill the rest with a random value, which you use as a (zero-padded, if necessary) seed to any stream cipher (http://en.wikipedia.org/wiki/Stream_cipher) then xor the value you want to encrypt with the first 32 bits of that (so your final message is the 32bits xor result, plus the random seed).

finally, i have no idea why everyone is convinced that these messages will/should/must be insecure. the security does not depend on the message size (it is the key size that is important). as far as i know, small blocks are only weak against long messages. here you do not have a long message (there's an important difference between able to guess a single message in 2^32 and knowing all messages after a similar "small" number of guesses).

Community
  • 1
  • 1
andrew cooke
  • 45,717
  • 10
  • 93
  • 143
  • Actually, that link is almost an exact duplicate of this question. Thanks. – Daniel Coffman Aug 09 '11 at 20:39
  • GregS suggested blowfish, which sounds like a reasonable choice for a a 64 bit block cypher. If you fill the 64 bit block with the 32 bit integer and 32 random bits this should be reasonably secure. There are a few weaknesses inherent in this problem, in particular simply guessing the plaintext has a 1/2^32 chance of succeeding, but I have no idea if that is a relevant attack on how the OP is using his integer. – CodesInChaos Aug 09 '11 at 20:41
1

Using base64 you get about 66 bits with 11 characters. If you increase your character set you get more. (If you consider Chinese symbols "human readable" you get far more)

I don't think secure asymmetrical encryption with such parameters is possible. RSA needs several hundred and better >1000 bit keys and blocks. Even elliptic curve crypto uses much bigger blocks than ~66 bit.

On the other hand you probably can get symmetric crypto with these properties. But I can't think of any standard algorithms which do since 64 bit keysize is a bit small nowadays and most cyphers with 64 bit blocks have 64 bit keys.

So I'd search a decent 64 bit block cypher with a larger (128bit+) key. I think a few of those exist but aren't used commonly.

And don't forget to add random padding to 64 bits. Having only 2^32 different plaintexts can be dangerous.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
0

There aren't any conventional asymmetric algorithms with a result that will fit in 11 characters or less.

For a really secure solution, you'll need a unique sequence number or identifier for each message; this would be something that you can use to initialize a cipher mode, like an IV for CBC or a counter for CTR mode. However, it's important that this seed isn't predictable for a given plain text.

Is there any other information in the message that you could use as a counter? It doesn't have to be a secret. Do you just want to obscure the integer, or truly encrypt it?

erickson
  • 265,237
  • 58
  • 395
  • 493
-1

XOR the value with a given key and then display the result as an hexadecimal string

Sylence
  • 2,975
  • 2
  • 24
  • 31
  • if there's any structure in the value being encoded then this is insecure - over several messages you can work out what the underlying key is. – andrew cooke Aug 09 '11 at 19:16
  • No it will always be less than 10 characters. 0 - FFFFFFFF @andrew: Well 'encrypting' 4 bytes and expecting the result to be 10 bytes or less is of course not secure ;) – Sylence Aug 09 '11 at 19:18
  • 2
    i don't understand why you are so sure that it is guaranteed insecure. for example, if both sides know the "sequence number" of the message then you can xor it with an encrypted counter. that does not have the same problem. the hard part here is asymmetry. – andrew cooke Aug 09 '11 at 19:24
  • Ok maybe I was a bit unclear about the key. I didn't mean a hard-coded key – Sylence Aug 09 '11 at 19:51