Length of Encrypted String - algorithm

I need to create a database column which will store a string encrypted using Triple DES. How do I determine the length of the encrypted string column?
(Answers for algorithms other than Triple DES are also welcome.)

Block-ciphers such as DES, 3DES and AES can only operate on blocks of bytes. DES and 3DES operate on block of 8 bytes and AES on blocks of 16 bytes.
To handle this, you usually apply a reversible padding to your plaintext before encrypting it. It will mostly always be "PKCS"-padding (also called PKCS5- or PKCS7-padding).
PKCS-padding adds at least one byte such that the padded text has a length divisible with the block-length (8 bytes for 3DES). The value of the padding-bytes is the number of bytes added. Fx. ABCDEF is padded to ABCDEF0505050505 and 0011223344556677 is padded to 0011223344566770808080808080808. Note that this is easy to remove: you just look at the final byte of the padded bytes, verify that it is between 1 and the block-length, and remove that number of bytes from the end (verifying that each removed byte has the correct value).
Finally, to answer your question: Assuming you are using 3DES with CBC encryption and PKCS-padding - which you probably are - the encryption of a string of length n will have length:
n + 8 - (n % 8)

Using Triple DES does not change the string's length but it will be rounded to the next 64 bit boundary. If you intend to "display" it, you'll have to encoded it (like in Base64 though.
As for other algorithms, it is difficult ot answer as there are plenty. Block ciphers will always pad input to match their block size whereas many stream ciphers will not.

Triple DES uses three 56-bit DES keys, giving 168 bit keys. It's block size is 64-bit.

Related

Schannel Cipher Naming Convention

I'm looking into disabling certain ciphers and I'm trying to wrap my head around how the block ciphers are named in Windows. Specifically what the numbers follow the name mean. For example, RC4 40/128, DES 56/56, AES 128/128 or AES 256/256. I thought maybe this was key size/block size but that doesn't make sense. Take AES 256/256. It is my understanding that for it to be AES it needs a block size of 128. Thus the last number can't specify block size. Or take the RC4 ciphers. It would appear that the first number is the key size but it's a stream cipher, so what is the 128? OR DES 56/56. I thought DES had a key size of 56 bits and a block size of 64 bits? Does anyone know the history or the reasoning behind the naming?

find encryption algorithm from known input and output

I have some inputs and outputs of a encryption function and i'm trying to find algorithm of it:
input:hello
output:eee5ab79be1ca8033fc790603b4d308c3c0a4e38
input:test
output:ebf3c7fb5cecf8ca04ca79dd0bbaa6e42120ffec
input:tennis
output:97e6335558d16337a5e712a3525a3766ab7a3454
input:a
output:0c57bfdc2835cdf0fab05fe08d37ffc5373f1ba8
input:b
output:67482459148ba04c2f12e83cdd18cbfe343978ee
input:c
output:380050d0dbf8293d16b7b4837d84abf4ae6b6d83
input:d
output:d0eae9775bac581b174dc4eaf0f6cc6cd284ad61
input:e
output:00626906c39804e9f441800c629900fd706002f8
input:f
output:7d6ae6cf3aa98f05bace0abc355474810f37c83d
input:0
output:324df299bcf4760d1523cb63ef5c4b2d1d4d371b
input:1
output:4a35df90d96cf1ed7aa008e99d1637b941d29605
input:2
output:2629ecf6a43d69aa06f7dfd5eabdba318d23132d
input:3
output:90225564ae81006f3747fb90d51dab4bac26fbac
input:4
output:3100cc28c4ef0f79e2d29c77a265aef1b2d0e70a
input:5
output:325fbdc73b2e874c287471e315949dc972846434
input:6
output:7d1bad0d82c2b62cfa0719f45acc50732579c206
input:7
output:89dd853798aea657f9ce236b248993b1f5c7bf55
input:8
output:83038f49e7954004aeafd2073b0c0c5a91d1ae7a
input:9
output:ab8fcf8532ed3c0367d6e5fa7230e4317296d6e4
outputs are hexadecimal and fixed length(40 characters)
inputs are unicode characters
Can anyone help me?
What you're asking isn't possible, because we would need to guess both the encryption algorithm and the encryption key
In addition, it appears that the algorithm in question has a 160-bit block size (which is why the output is a fixed 160 bits - presumably if it were given 161 bits of input then its output would be 320 bits), but I am not aware of any encryption algorithm with a 160-bit block size - block sizes are typically a power of 2 (e.g. 128 bits or 256 bits). Maybe it's an encryption algorithm with a 128 bit block size plus a 32 bit checksum, but that's just complicating an already impossible task.

how to represent a n-byte array in less than 2*n characters

given that a n-byte array can be represented as a 2*n character string using hex, is there a way to represent the n-byte array in less than 2*n characters?
for example, typically, an integer(int32) can be considered as a 4-byte array of data
The advantage of hex is that splitting an 8-bit byte into two equal halves is about the simplest thing you can do to map a byte to printable ASCII characters. More efficient methods consider multiple bytes as a block:
Base-64 uses 64 ASCII characters to represent 6 bits at a time. Every 3 bytes (i.e. 24 bits) are split into 4 6-bit base-64 digits, where the "digits" are:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
(and if the input is not a multiple of 3 bytes long, a 65th character, "=", is used for padding at the end). Note that there are some variant forms of base-64 use different characters for the last two "digits".
Ascii85 is another representation, which is somewhat less well-known, but commonly used: it's often the way that binary data is encoded within PostScript and PDF files. This considers every 4 bytes (big-endian) as an unsigned integer, which is represented as a 5-digit number in base 85, with each base-85 digit encoded as ASCII code 33+n (i.e. "!" for 0, up to "u" for 84) - plus a special case where the single character "z" may be used (instead of "!!!!!") to represent 4 zero bytes.
(Why 85? Because 845 < 232 < 855.)
yes, using binary (in which case it takes n bytes, not surprisingly), or using any base higher than 16, a common one is base 64.
It might depend on the exact numbers you want to represent. For instance, the number 9223372036854775808, which requres 8 bytes to represent in binary, takes only 4 bytes in ascii, if you use the product of primes representation (which is "2^63").
How about base-64?
It all depends on what characters you're willing to use in your encoding (i.e. representation).
Base64 fits 6 bits in each character, which means that 3 bytes will fit in 4 characters.
Using 65536 of about 90000 defined Unicode characters you may represent binary string in N/2 characters.
Yes. Use more characters than just 0-9 and a-f. A single character (assuming 8-bit) can have 256 values, so you can represent an n-byte number in n characters.
If it needs to be printable, you can just choose some set of characters to represent various values. A good option is base-64 in that case.

Hash function to produce a code of 30 chars?

I need to hash a message into a string of 30 chars. What's the best and most secure hash function for this usage?
Thirty characters (bytes) is 240 bits.
If you can't move the goal-post to allow 32 characters, then you will probably end up using SHA-1, which generates 160-bits or 20 bytes. When Base-64 encoded, that will be 28 characters. If you use a hex-encoding, it will be 40 characters, which is nominally out of range. With 32 characters, you could use SHA-256, but Base-64 encoding would increase that size (to 44 characters) and hex-encoding increases the size to 64 characters.
If you must use hex-encoding and can go to 32 bytes, then MD5 - which generates 128 bits - could be used, though it is not recommended for any new systems. With Base-64 encoding, MD5 uses 24 characters. Otherwise, you are using very minimally secure algorithms - not recommended at all.
Just use SHA1 and trim to 30 characters.
import hashlib
hash = hashlib.sha1("your message").hexdigest()[:30]
It's been proven that cutting characters off a cryptographically secure hash function such as SHA1 has negligible effects on its security (can't find the reference now though)

Encrypt printable text so result is still printable (can be typed)

I want to encrypt some info for a licensing system and I want the result to be able to be typed in by the user.
Update: This operation must be reversible (decrypt-able)
E.g.,
Encrypt ( ComputerID+ProductID) -> (any standard ASCII character that can be typed. Ideally maybe even just A-Z).
So far what I did was to convert the encrypted text to HEX (so it's any character from 0-F) but that doubles the number of characters.
I'm using VB6.
I'm thinking I'd do some operation on each pair of (Input$(x) and Key$(x)) and then do a MOD to keep it within a range of ascii values (maybe 0-9-A-Z)
Any suggestions of a good algorithm?
Look into Base64 "encryption."
Base 64 will convert a number into 64 different ASCII characters, verses hex which is only 16 different ASCII characters... Making Base64 more compact and what you are looking for.
EDIT:
Code to do this in VB6 is available here: http://www.nonhostile.com/howto-encode-decode-base64-vb6.asp
Per Fuzzy Lollipop, below, Base32 looks like an even better option. Bonus points if you can find an example of that.
EDIT: I found an example of Base32 for VB6 although I've not tried it yet. -Clay
encode the encrypted bytes in HEX, or Base32 or Base64
Do you want this to be reversible -- to recover the IDs from the encrypted text? If so then it matters how you combine the key and input strings.
Usually you'd XOR each byte pair (work with byte arrays to avoid Unicode issues), circulating on the key string if it's shorter than the input. You can then use Base N encoding (32, 64 etc) to generate the license string.
Both operations are reversible: you can recover the XORed strings from the Base N string, then XOR with the key again to get the original IDs.
If you don't care about reversing the operations, then any convolution of key and ID will do. XOR is just the simplest.

Resources