Good Afternoon all,
I am working over rsa encryption and decryption, for more security i am also using padding in cipher text, for different input (amit) , i am getting different length output like-
plain text- amit
cipher text-10001123A234A987A765A
My problem is- For big plain text ,my algo generate large size cipher text, and i thought,
it is wastage of resources to keep long string in database ,
Is there any way with the help of that i can compact cipher and convert real cipher when i will require?
In order for the algorithm to be encryption and not just hashing, it must be reversible. To be reversible, the output must contain as much information as the input, and so is unlikely to be significantly shorter.
You may compress the data before encryption. There's not a lot else you can do unless you're willing to give up the ability to recover your original text from the ciphertext.
There are a couple of possibilities:
Change your encryption scheme there are schemes where the size is same as the input size
Compress your data before you encrypt, this will be effective only if you have a large block of text to encrypt and then there's the additional overhead of decrypting too.
This doesn't apply to RSA specifically, but: any secure cipher will give output close to indistinguishable from a random bit pattern. A random bit pattern has, per definition, maximum information theoretic entropy, since for each bit, both 0 and 1 are equally likely.
Now, you want a lossless compression scheme, since you need to be able to decompress to the exact data you originally compressed. An optimal compression scheme will maximize the entropy of it's output. However, we know that the output of our cipher already has maximum entropy, so we can't possibly increase the entropy.
And thus, trying to compress encrypted data is useless.
Note: Depending on your encryption method, compression might be possible, for example, when using a block cipher in EBC mode. RSA is a completely different beast altogether though, and, well, compressing won't do anything (except quite possibly make your final output bigger).
[Edit] Also, the length of your RSA ciphertext will be in the order of log n. With n your public modulus. This is the reason that, especially for small plaintexts, public key crypto is extremely 'wasteful'. You normally employ RSA to setup a (smaller, e.g. 128-bit) symmetric key between two parties and then encrypt your data with a symmetric key algorithm such as AES. AES has a block size of 128 bits, so if you do straightforward encryption of your data, the maximum 'overhead' you incur will be length(message) mod 128 bits.
erm ... you wrote in a comment here that you apply RSA encryption to all single characters:
i am using rsa- it perform over
numbers to convert amit in cipher text
first i do a->97 m->109 i->105..and
then apply rsa over 97 ,109 ... then i
get different integers for 109, 105 or
... i joined that all as a string...
a good advice: don't do that since you will lose the security of RSA
if you use RSA in this way, your scheme becomes a substitution-cypher (with only one substitution alphabet) ... given a reasonably long cypher-text or a reasonable number of cypher-texts, this scheme can be broken by analyzing the frequency of cypher-text-chars
see RSAES-OAEP for a padding scheme to apply to your plaintext before encryption
Related
If I give you the MD5 checksum of a string, can you generate the SHA checksum?
Or Vice Versa?
If I give you an MD5 checksum and a SHA checksum, can you tell me whether they're generated from the same source string?
(Obviously I'm excluding anything like locating the source string from a rainbow table, etc. etc.)
No. Both are one-way hashes, so the information contained in the original source string is lost in the checksum.
Even if you do have the "original" string as you say, there will be some other data out there that when hashed, results in a collision. This is because MD5 and SHA1 are not perfect hash functions. In the case of MD5, each hash can potentially have an infinite number of collisions. Then there is no guarantee that the generated SHA checksum of the "original" string is actually what you seek.
Disclaimer: I have very little experience with the theoretical side, so you may want to verify with other resources.
As we know, Hill cipher is a classic cipher in cryptography and is mostly used for encrypting text. I need to encrypt a file (such as .doc, .ppt, .jpeg, etc), and not just the contents of file. I already searched on the Internet, but I didn't find much research that focuses on file encryption.
What I found : encrypting text content in .txt doesn't encrypt the .txt file.
Using Java or .Net or Python (pick one or some), how to implement Hill Cipher to encrypt files as I explained above?
As a note, this question is not for my homework or assignment. I am just confused and curious about how one can implement the Hill Cipher to encrypt a file. Thank you.
The Hill cipher, like most classical ciphers from the pre-computer era, was traditionally used to only encrypt letters: that is, the valid inputs would consist only of the 26 letters from A to Z (and, in some variants, possibly a few extra symbols to make the alphabet size a prime number).
That said, there's no reason why you couldn't use a variant of the Hill cipher with, say, an alphabet size of 256, allowing you to directly encrypt input consisting of arbitrary bytes.
For a key, you'd need a random matrix that is invertible modulo 256, that is, a matrix consisting of random values from 0 to 255 chosen such that its determinant is an odd number. An easy way to generate such matrices is to just pick the matrix elements uniformly at random, calculate the determinant, and start over if it happens to be even. On average, you'll need two tries to succeed. Of course, for decryption, you'll also need to actually calculate the inverse matrix.
All that said, it's worth noting that the Hill cipher, on its own, is very easy to break. Indeed, even its inventor Lester S. Hill realized this, and only recommended it for use in combination with a substitution cipher, in what we might today consider a primitive substitution-permutation network.
Of course, nowadays we have access to much more efficient and secure ciphers, such as, say, AES. For any practical encryption tasks (as opposed to just learning exercises), you should use those rather than trying to develop your own.
I'm working on a project that involves writing low-level C software for a hardware implementation. We are wanting to implement a new feature for our devices that our users can unlock when they purchase an associated license key.
The desired implementation steps are simple. The user calls us up, they request the feature and sends us a payment. Next, we email them a product key which they input into their hardware to unlock the feature.
Our hardware is not connected to the internet. Therefore, an algorithm must be implemented in such a way that these keys can be generated from both the server and from within the device. Seeds for the keys can be derived from the hardware serial number, which is available in both locations.
I need a simple algorithm that can take sequential numbers and generate unique, non-sequential keys of 16-20 alphanumeric characters.
UPDATE
SHA-1 looks to be the best way to go. However, what I am seeing from sample output of SHA-1 keys is that they are pretty long (40 chars). Would I obtain sufficient results if I took the 40 char key and, say, truncated all but the last 16 characters?
You could just concatenate the serial number of the device, the feature name/code and some secret salt and hash the result with SHA1 (or another secure hashing algorithm). The device compares the given hash to the hash generated for each feature, and if it finds a match it enables the feature.
By the way, to keep the character count down I'd suggest to use base64 as encoding after the hashing pass.
SHA-1 looks to be the best way to go. However, what I am seeing from sample output of SHA-1 keys is that they are pretty long (40 chars). Would I obtain sufficient results if I took the 40 char result and, say, truncated all but the last 16 characters?
Generally it's not a good idea to truncate hashes, they are designed to exploit all the length of the output to provide good security and resistance to collisions. Still, you could cut down the character count using base64 instead of hexadecimal characters, it would go from 40 characters to 27.
Hex: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Base64: qUqP5cyxm6YcTAhz05Hph5gvu9M
---edit---
Actually, #Nick Johnson claims with convincing arguments that hashes can be truncated without big security implications (obviously increasing chances of collisions of two times for each bit you are dropping).
You should also use an HMAC instead of naively prepending or appending the key to the hash. Per Wikipedia:
The design of the HMAC specification was motivated by the existence of
attacks on more trivial mechanisms for combining a key with a hash
function. For example, one might assume the same security that HMAC
provides could be achieved with MAC = H(key ∥ message). However, this
method suffers from a serious flaw: with most hash functions, it is
easy to append data to the message without knowing the key and obtain
another valid MAC. The alternative, appending the key using MAC =
H(message ∥ key), suffers from the problem that an attacker who can
find a collision in the (unkeyed) hash function has a collision in the
MAC. Using MAC = H(key ∥ message ∥ key) is better, however various
security papers have suggested vulnerabilities with this approach,
even when two different keys are used.
For more details on the security implications of both this and length truncation, see sections 5 and 6 of RFC2104.
One option is to use a hash as Matteo describes.
Another is to use a block cipher (e.g. AES). Just pick a random nonce and invoke the cipher in counter mode using your serial numbers as the counter.
Of course, this will make the keys invertible, which may or may not be a desirable property.
You can use an Xorshift random number generator to generate a unique 64-bit key, and then encode that key using whatever scheme you want. If you use base-64, the key is 11 characters long. If you use hex encoding, the key would be 16 characters long.
The Xorshift RNG is basically just a bit mixer, and there are versions that have a guaranteed period of 2^64, meaning that it's guaranteed to generate a unique value for every input.
The other option is to use a linear feedback shift register, which also will generate a unique number for each different input.
I am currently using openSSL on linux c. I would like to ask if the cipher block size is always fixed to 16 unsigned char? The reason for this is because I am encrypting a massively large data. The problem is based on the description of SSL, the ecrypted cipher block of the previous block is XOR to the next plain text block when encrypting. Is there a way to icrease the size of the cipher block?
For example if I had a Gigabyte of data to encrypt, it would take Gigabyte/16byte times of encryption. Is there a standard way to force the AES_cbc_encrypt method call to use a vi that is not 16 byte? The still follows the standard? The reason for this is the encrypted text would be read by another program on another system that uses another CGC standard library.
No, the AES standard mandates a 16 byte block size. The original algorithm which it was based on, Rijndael, allowed more flexibility, but you can't rely on another AES implementation to support that.
For block ciphers, the size of the block is the property of the algorithm in question. DES used 8 bytes for instance. Stream ciphers (RC4 for example) on the other hand do not use fixed block sizes, they are effectively pseudo random generators seeded with the key.
But anyway, the performance of ciphers are published with the block size in mind, and AES does about 160mbyte/sec on a recent CPU. You can measure this using "openssl speed aes".
So, if you want to encrypt 1Gb of data, I'd be more concerned with moving all that data from disk, to memory and back again, rather than the encryption speed of AES itself.
I need to encrypt an ISO 8583 message... the problem here is that the message is longer than the key. I need some one help me how to encrypt this string.
For example: I have 300 chars in my string; should I encrypt each 16 chars alone then concat them, since my master key length is 16 bytes?
I appreciate your help...
ISO 8583-1:2003 Financial transaction card originated messages -- Interchange message specifications -- Part 1: Messages, data elements and code values.
DES is a block cipher, and block ciphers have different modes of operation.
The mode you mentioned is known as ECB (Electronic Codebook), and is not very secure (actually, neither is DES, but more on that later).
I'd suggest you use CBC or some other mode.
You can read about block cipher modes of operation here: Block cipher modes of operation
As for the cipher itself, I'd suggest you avoid using DES if this is at all possible. DES is extremely easy to crack nowadays. Please use AES, or at least 3DES if AES is not available.
EDIT: In response to the updated question, yes, you would need to pad the last block if the plaintext size is not a multiple of the block size.
There are many different modes of operation for a block cipher.
If you just need to applay ECB to your plain text, just split the plain text into equally sized blocks of size 8 bytes (DES block size) and encrypt each separately.
Depending on what you want to achieve, you could also use
ECB which encrypts block wise with each block being independent from all other (previous) blocks. Drawback: known plain text attacks can reveal patterns in your cipher text because the same plain text will always be encrypted to the same cipher text
CBC here you have an initialization vector and each blocks depends on all previously encrypted blocks. This is why you need an IV for the first block.
CFB this is an interesting one because it allows you to turn your block cipher into a stream cipher, which might be useful if you want to encrypt a video stream or whatever (similarly for OFB which basically generates a key stream)
CTS cipher text stealing might be of use if you want to encrypt data but want to avoid padding. A usage example might be to encrypt a blob in your database, which you cannot resize after it has been written to the DB.
There are still many more modes, but these are the most commonly used ones (imho).
As others have pointed out visit Wikipedia for all the details.
Update:
As for the padding, you have different possibilities. I'd recommend to use the ANSI X.923 standard which basically requires you to pad the last buffer with zeroes and append a counter in the last byte which gives you the number of valid bytes in the last block. The same idea is used in ISO10126 but this time padding is done with random bytes.
Note that you can avoid padding at all when using CTS.
Maybe ask yourself if it's actually easier to use a crypto library to do the job for you.
If you're using C++ go for Crypto++ (not so straightforward, but consistent c++ style), Java and .NET have built in crypto providers. If you want to use plain C i can recommend libTomCrypt (very easy to use).
The key length does not impose a limit on the message size. The message can be as long as you want, and your 128-bit key (nonstandard for DES?) will still be good. The DES cipher operates on blocks of bytes, one block at a time. Standard DES uses a 56-bit key (plus 8 parity bits) and 64-bit blocks.
should I encrypt each 16 chars alone
then concat them, since my master key
length is 16 bytes?
Ciphers in general do not require the key and block sizes to be the same; they can define complicated operations taking a given block of cleartext and transforming it with the key to a block of ciphertext (usually of the same size). When multiple blocks need to be encrypted, a mode of operation is specified to describe how one block relates to the next block in the process.
When operating in the electronic codebook (ECB) mode, the message is divided into blocks, and each block of cleartext is encrypted separately with the same key (the resulting blocks of ciphertext are then concatenated). Like other modes of operation for DES (i.e. CBC, CFB, OFB), this approach has its pros and cons. You will need to pick the mode most suitable for your application.
Btw, you should also be aware that DES is now considered insecure.
You need to look up encryption modes - which have names such as Cipher Block Chaining (CBC) and the 'do not use' mode Electronic Code Book (ECB), and even some exotic names like the Infinite Garble Extension (IGE). That page has a beautiful illustration of why the ECB mode should not be used.
CBC is a standard, solid mode of operation. OFB and CFB are also widely used.
You realize that the US Federal Government no longer uses plain DES because it is not secure enough (because it uses a 56-bit key and can be broken by brute force)? Triple-DES is just about tolerated - it has a 112-bit or 168-bit key, depending on which way you use it. The standard, though, is Advanced Encryption System, AES. Unless you have backwards compatibility reasons, you should use AES and not DES in new production code.
Also, you should know the answers to these questions before trying to write production code. I trust this is in the nature of homework or personal interest.
You might want to encrypt for the following reason:
Transmit secured data that is the PIN Block (Data Element 52), this one is taken care of by the HSM, by the time you translate from the acquirer key to the issuer key.
or to MAC the message, then you would select some fields to hash and append to the end of the message (usually Data Element 124 or 128)
or you want to store the ISO 8583 message and want to comply with PCI DSS regulations, in this case you would encrypt the following data elements if present
DE 2 - Card Number
DE 14 - Expiry Date
DE 35 - Track II
DE 45 - Track I
DE 48 - EMV (Chip) Data (MasterCard TLV)
DE 52 - PIN Block
DE 55 - EMV (Chip) Data (Visa)
one more thing, your Master Key should be 128 bits to comply with Visa mandates (Triple DES Mandates to have LMK at least double length key that is 32 digits - 128 bits key)