How can I convert a 96 bit key to a 64 bit key? I have a DES key that is 96 bits long (i.e 745347651281) . I want to convert this to 64 bit which I will use to decrypt a DES ciphertext.
Update:
There was an "original key" encrypted by RSA
The "original key" was decrypted using RSA to give us this (i.e 745347651281)
This (i.e 745347651281) is now supposed to be used to decryped a DES
file.
Note : The "original key" was in hex format which I converted to integer(base 16) before doing RSA decryption.
The key you have displayed is 48 bits in size, not 96 bits in size - if it is considered to be specified hexadecimals. A DES key without parity would be 56 bits in size. This means that you have to create the parity bits that are missing. The parity of DES is described as such:
One bit in each 8-bit byte of the KEY may be utilized for error detection in key generation, distribution, and storage. Bits 8, 16,..., 64 are for use in ensuring that each byte is of odd parity.
Note that the bits are numbered starting at the left with value 1, meaning that the least significant bit of each byte is used for parity. So you have to distribute the bits you have been given over the bytes, and then adjust the parity of each byte by possibly flipping the least significant bit (using XOR with 1).
Usually libraries have support for this kind of operation. In Java you can do this by generating the DES key using SecretKeyFactory for instance.
Related
I'm working on RSA and ElGamal encryption systems but I'm stuck. I've written those algorithms, I know how it works. How can I change 256 byte chunks of file into number from range [1, 2^2048]? Because I can't pass 256 bytes as an argument with generated public key to encrypt.
I have a data that needs to be stored in a database as encrypted, the maximum length of the data before encryption is 50 chars (English or Arabic), I need to encrypt the data using AES-128 bit, and store the output in the database (base64string).
How to know the length of the data after encryption?
Try it with your specified algorithm, block size, IV size, and see what size output you get :-)
First it depends on the encoding of the input text. Is it UTF8? UTF16?
Lets assume UTF8 so 1 Byte per character means 50 Bytes of input data to your encryption algorithm. (100 Bytes if UTF16)
Then you will pad to the Block Size for the algorithm. AES, regardless of key size is a block of 16 Bytes. So we will be padded out to 64 Bytes (Or 112 for UTF 16)
Then we need to store the IV and header information. So that is (usually, with default settings/IV sizes) another 16Bytes so we are at 80 Bytes (Or 128 for UTF16)
Finally we are encoding to Base64. I assume you want string length, since otherwise it is wasteful to make it into a string. So Base 64 bloats the string using the following formula: Ceil(bytes/3) * 4. So for us that is Ceil(80/3) = 27 * 4 = 108 characters (Or 172 for UTF 16)
Again this is all highly dependent on your choices of how you encrypt, what the text is encoded as, etc.
I would try it with your scenario before relying on these numbers for anything useful.
I am new to encryption methods and i want to know what is the meaning of 128 bit key. Does it mean the key has 128 characters or when we convert key to the binary, and then that binary has 128 digits or cipher that created using key and plain text has 128 characters ?
The key is 128 (binary) bits. That's all it means.
AES supports key sizes of 128, 192, or 256 bits.
AES has a fixed block size of 128 bits, which means it en/decrypts data in chunks of 16 bytes at a time. The plaintext/cipher text can be any length of course (and is padded out to a multiple of 16 bytes).
Good crypto implementations will use a Key Derivation Function which takes a password (or keyfile, etc) of any length, and generates a key suitable for the encryption algorithm in question.
We're looking for a way to encrypt a 16 digit number (could be 10-20 digits), with the following requirements:
Output is also a number
Output doesn't double (or greatly increase the number of digits)
Doesn't require pre-storing a massive mapping table
Ok with moderate to low security
Simple and very low security: Add something, then XOR the number with another number of similar size. Only viable if nobody has access to the source code. And anybody who has access to the program (even without source) and who can run it with a few samples (0, 1000, 10000, 10000000) will be able to figure it out.
Depending on language:
uint64_t theNumber;
uint64_t cryptbase1= 12345678909876, cryptbase2= 234567890987654;
// encrypt
uint64_t encrypted= (theNumber + cryptbase1) ^ cryptbase2;
// decrypt
uint64_t decrypted= (encrypted ^ cryptbase2) - cryptbase1;
I can imagine a 16 digit to 20 digit encryption algorithm:
Encrypt:
Convert the 16 digit number into its binary representation (54 bits needed).
Use a block cipher algorithm with a small blocksize (e.g. Triple-DES has a block size of 64 bits) to encrypt the 54 bits.
Convert the encrypted 64 bits into its 20 digit representation.
Decrypt:
Convert the 20 digit number into its binary 64 bit representation.
Use the block cipher algorithm to decrypt.
Convert the 64 bits into its 20 digit representation. The left 4 digits have to be 0, 16 digits remain.
You are probably looking at a block cypher with a block size able to hold up to 20 decimal digits. You can use Hasty Pudding cipher, which has a variable block size, or alternatively you could roll your own simple Feistel cipher with an even number of bits per block. You do not seem to need a very high level of security, so a simple Feistel cipher with four or six rounds would probably be easier.
I use a simple Feistel cipher for integer permutations, and the F function is:
// The F function for the Feistel rounds.
private int F(int num, int round) {
// XOR with round key.
num ^= mRoundKeys[round];
// Square, then XOR the high and low parts.
num *= num;
return (num >>> HALF_SHIFT) ^ (num & LOW_16_MASK);
} // end F()
You do not seem to need anything more complex than that. If you want cryptographic security, then use Hasty Pudding, which is a lot more secure.
Any binary block of the appropriate size can be represented as decimal digits.
I was wondering:
1) if I compute the digest of some datas with SHA-512 => resulting in a hash of 64 bytes
2) and then I sign this hash with RSA-1024 => so a block of 128 bytes, which is bigger than the 64 bytes of the digest
=> does it mean in the end my signed hash will be exactly 128 bytes?
Thanks a lot for any info.
With RSA, as specified by PKCS#1, the data to be signed is first hashed with a hash function, then the result is padded (a more or less complex operation which transforms the hash result into a modular integer), and then the mathematical operation of RSA is applied on that number. The result is a n-bit integer, where n is the length in bits of the "modulus", usually called "the RSA key size". Basically, for RSA-1024, n is 1024. A 1024-bit integer is encoded as 128 bytes, exactly, as per the encoding method described in PKCS#1 (PKCS#1 is very readable and not too long).
Whether a n-bit RSA key can be used to sign data with a hash function which produces outputs of length m depends on the details of the padding. As the name suggests, padding involves adding some extra data around the hash output, hence n must be greater than m, leaving some room for the extra data. A 1024-bit key can be used with SHA-512 (which produces 512-bit strings). You could not use a 640-bit key with SHA-512 (and you would not, anyway, since 640-bit RSA keys can be broken -- albeit not trivially).