Determining a Private Key (Diffie-Hellman) - java

I've been given a challenge and it has to do with testing a friend's encryption process.
It's a Diffie-Hellman exchange process, and here are the known variables / constants:
P, G
my generated private key (variable)
my generated public key(variable)
the recipients public key (constant).
When looking at my private key - P and G are both within it. For example, the first 'x' bytes seem to have no relation to anything, then the next 'y' bytes are P, the next two bytes are static, and the next 'z' bytes are G, the remainder are variable.
The process is to encrypt a file, and send it to a device, which will in turn decrypt it - my ideas of attack are this:
try to duplicate the secret shared key. The problem here is that is fine as long as I know my generated private key, at which case - I don't for the files he's given me.
Try to find the recipients private key. Here, I could brute force my way in - but would take forever unless I had some sort of supercomputer.
Are there any other options to look at when trying to attack this?

I probably should keep my mouth shut, but it is also an opportunity for those interested in Diffie-Hellman to learn something:
Simple implementation of Diffie-Hellman to generate the shared key is vulnerable to man-in-the-middle attacks. However, most implementation of DH tackle this issue properly by adding authentication between Alice and Bob.
If your implementation of DH allows declaring a new set of PQG, you could request the other peer to use a new weak set. If Bob does not verify the quality of this set, then it is vulnerable to attacks.
DH requires Alice to send X = g^x, if Bob does not check the quality of X, he is vulnerable, since the space of possible values of the secret key can significantly be reduced by Eve in the middle.
If your implementation does not remember compromised keys, they can be re-used by Eve.
If your implementation does not remember compromised certificates, they can be re-used by Eve.
If your implementation does not check certificates, Eve will have fun for sure.

Related

how to decrypt using DatatypeConverter MD5 In JAVA?

public static void main(String[] args) {
String s = "text";
hash=DatatypeConverter.printHexBinary(MessageDigest.getInstance("MD5").digest(s.getBytes("UTF8")))
System.err.println(hash);
}
You can't. That's what hashing is about. This is not a API or library limitation but a mathematical one, which is there by design.
You need to understand that hashing and encryption/ decryption are two completely different things (which are often used together).
Hashing
A hash, or to be precise, a cryptographic hash, is the result of a mathematical one-way function which means it is meant to be irreversible. Once something is hashed, it is not possible to get the text that was hashed back from it. This is at least true for good hash algorithms, which are not considered broken. MD5 as well as SHA1 are considered broken, so if you need this in a security context, use SHA-256 or even SHA-512 instead. If you just need this for a checksum, MD5 should be fine.
You can just use an MD5 hash value and type it into Google and get the result back. That is not what you want from a hash function. E.g. take your the hash 1cb251ec0d568de6a929b520c4aed8d1 which is the MD5 hash of your message text and you'll get a website which shows you the original text.
Another property of a hash it that for two different inputs it should ideally never have the same output. That is of course impossible as the set of possible messages to hash is much much bigger then the set of possible hash messages as hashes have a fixed length. But it should not be possible to generate such a hash collision artificially following some algorithm or clever input.
The only way to find out what was hashed is to hash many messages (brute-force) and see if the computed hash matches the hash to be cracked. See Rainbow tables for more information on this.
Hashes are mostly used to ensure integrity i.e. no modification was done to a message sent over the network. It is often used in conjunction with encryption algorithms (that's probably where your confusion originates from) as you need more than integrity to guarantee secure communication i.e. additionally authentication (e.g. by using certificates) and confidentiality (this is provided by encryption algorithms).
Encryption
An encryption function is a function which takes a message and a key and produces a result which is not readable unless you have the key. Side note: there may be one or two keys for encryption/ decryption depending on the algorithm you use (symmetric vs. asymmetric). If you have the key, it is reversible by applying the decryption function. If it was a one-way function like a hash, encryption would make no sense, as a recipient of a message would not be able to retrieve the message.

Hashing and Dehasing

So, I'm attempting to write a cryptography method that uses a hash that both the sender and the receiver know. I'm confused as to how to dehash a message.
For example, the sender sends a the message
M: 50 and hashes it
So 50 % 30 = 20.
H = 30
So after hashing, the resulting message would be 30.
How would the receiver be able to dehash the message to receive the original with knowing the hash?
There's no code or anything. Just an important concept that I wish to grasp.
EDIT: So, I have a general understanding of encryption and decryption. For the sake of understanding. How would I get the original message using RSA?
For for example,
Sender Private Key: 55,27
Sender Public Key: 55,3
Receiver Private Key: 35,29
Receiver Public Key: 35, 5
Is this possible?
What you are looking for is encrypting and decrypting. Hashing is a one way function which usually loses information making it impossible to recreate the original message.
Is there any way to receive the original message after hashing through encryption?
When you use encryption, you create some bytes which look random and can look like a long hash value. The difference is that the data can be decrypted back to the original information, whereas with hashing this is designed to be as hard as possible.
If so, which encryption/decryption method do I use?
The key decision to make is whether you want symmetric or asymmetric encryption. Symmetric is faster but requires the key for decryption be the same as encryption i.e. both the point of encryption and decryption needs to be secure. If you use asymmetric encryption, you can allow one end to either decrypt or encrypt but not both. i.e. only one end needs to be secure.

Token Generation Scheme Comparison

We're in the process of defining a time-sensitive token generation scheme for our SOAP services. Currently we have two ideas and we're not sure which is better and why.
Scheme 1:
The rands at the beginning and end don't add any particular value, but the idea is to add a small layer of salting.
Sender
<token>rand(6) ++ encrypt(time) ++ rand(6)</token>
Receiver
enc = token.substring(6,token.len-6)
time = decrypt(enc)
assert(time is within +/- range)
Scheme 2:
Here we encrypt the rands into the token.
Sender
<token>encrypt(rand(6) ++ encrypt(time) ++ rand(6))</token>
Receiver
dec = decrypt(token)
time = dec.substring(6,dec.len-6)
assert(time is within +/- range)
So I'm not only looking for an answer for which is best, but WHY it's best. I've looked for some documents or best practices, but short of IEEE documents, I haven't found much. If you have any documents you can point us to, we'd love that!
Of the two schemes you present, the first doesn't really address the goal of salting. From Wikipedia:
The primary function of salts is to defend against dictionary attacks
and pre-computed rainbow table attacks
and I would expect the salting to encrypt the same sequence differently each time you encrypt it. e.g. (using your examples)
encrypt(rand(6) + encryptable)
such that multiple encryptions of the same sequence require individual decrypting.
If you need a unique token, rather than rely on a timestamp, why not use a GUID ?

Difference between SALT and KEY. Encryption

Alright, so im trying to learn a little about Encrypting messages in my java application. I just found out that SALT and KEY aren't the same.
Can someone help me understand what the difference between the two is?
The key is, crudely, the equivalent of a password; you use it to encrypt a message, and then the same key gets used to decrypt it back to the original plaintext. (Well, it gets a little more complex, once you have public and private keys, and so on.)
A salt is most typically encountered with cryptographic hash functions, not encryption functions. The idea is that rather than hashing just your data (e.g. a password), you hash data+salt, where salt is typically a randomly-generated string. They have (at least) two purposes:
To foil an attacker who has access to the hashed data from identifying a collision using a rainbow table.
To slow down an attacker who's trying a brute-force attack.
The key is essentially the password with which you lock the original content.
To make the password more difficult to reverse engineer, you can add a salt to the produced encryption.
To give an obviously simple example, lets say you want to encrypt a character string. Your encryption routine is to reverse the word.
So, for the string "Hello, World", after running encryption, your string would be "dlroW ,olleH".
You could then add a salt to it. In this example, the salt will be "foo", so the result after salting would be "dlroW ,olleHfoo".
Now, if someone managed to reverse engineer your encryption algorithm, they'd get "oofHello World", which is not the original message, and thus your information is still safe!
This really comes into use when you iteratively encrypt, eg,
result = salt + encrypt(salt+encrypt(salt+encrypt(message))).

Is there a difference between ECDH and ECDSA keys?

I'm building a network application that uses BouncyCastle as a cryptography provider. Let's say you have this to generate a keypair:
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime192v1");
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");
g.initialize(ecSpec, new SecureRandom());
KeyPair pair = g.generateKeyPair();
I'm confused as to why you're getting an instance of an ECDSA KeyPairGenerator. Why doesn't it just say EC? I know that there's an ECDH Key type that is shipped with BouncyCastle, but I thought that the two represented the same stuff about the points on the curve -- or am I completely wrong with the theory behind it?
The reason that I ask is that right now my application uses ECDH fine to establish an AES secret key, but now I want to use the same EC key to sign each message using ECDSA.
ECDSA and ECDH are from distinct standards (ANSI X9.62 and X9.63, respectively), and used in distinct contexts. X9.63 explicitly reuses elements from X9.62, including the standard representation of public keys (e.g. in X.509 certificates). Hence, ECDSA and ECDH key pairs are largely interchangeable. Whether a given implementation will permit such exchange, however, is an open question. Historically, (EC)DSA and (EC)DH come from distinct worlds.
Note, though, that usage contexts are quite distinct. There is a bit more to cryptography than computations on elliptic curves; the "key lifecycle" must be taken into account. In plain words, you do not want to manage key agreement keys and signature keys with the same procedures. For instance, if you lose your key agreement key (your dog eats your smartcard -- do not laugh, it really happens), then you can no longer decrypt data which was encrypted relatively to that key (e.g. encrypted emails sent to you, and stored in encrypted format). From a business point of view, the loss of a key can also be the loss of an employee (the employee was fired, and was struck by a bus, or retired, or whatever). Hence, encryption keys (including key agreement keys) must often be escrowed (for instance, a copy of the private key is printed and stored in a safe). On the other hand, loss of a signature key implies no data loss; previously issued signatures can still be verified; recovering from such a loss is as simple as creating a new key pair. However, the existence of an escrow system tends to automatically strip signatures of any legal value that could be attached to them.
Also, on a more general basis, I would strongly advise against using the same private key in two distinct algorithms: interactions between algorithms have not been fully explored (simply studying one algorithm is already hard work). For instance, what happens if someone begins to feed your ECDH-based protocol with curve points extracted from ECDSA signatures which you computed with the same private key ?
So you really should not reuse the same key for ECDH and ECDSA.

Categories