Initial GitHub export
This commit is contained in:
committed by
Thai Duong
parent
c662a0ac90
commit
f7ecb0dfad
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016 Google Inc. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.security.wycheproof;
|
||||
|
||||
import com.google.security.wycheproof.WycheproofRunner.ProviderType;
|
||||
import com.google.security.wycheproof.WycheproofRunner.SlowTest;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Testing DHIES.
|
||||
*
|
||||
* @author bleichen@google.com (Daniel Bleichenbacher)
|
||||
*/
|
||||
// Tested providers:
|
||||
// BC (not recommended)
|
||||
//
|
||||
// TODO(bleichen):
|
||||
// - maybe again CipherInputStream, CipherOutputStream,
|
||||
// - byteBuffer.
|
||||
// - Exception handling
|
||||
// - Is DHIES using the key derivation function for the key stream?
|
||||
// - BouncyCastle knows an algorithm IES. Is this the same as DHIES?
|
||||
public class DhiesTest extends TestCase {
|
||||
|
||||
// TODO(bleichen): This is the same as DhTest.java
|
||||
// We could move this into some TestUtil.
|
||||
public DHParameterSpec ike2048() {
|
||||
final BigInteger p =
|
||||
new BigInteger(
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
|
||||
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
|
||||
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
+ "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
|
||||
16);
|
||||
final BigInteger g = new BigInteger("2");
|
||||
return new DHParameterSpec(p, g);
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: This test uses weak crypto (i.e. DHIESWithAES). Checks that key agreement using DHIES
|
||||
* works in the sense that it can decrypt what it encrypts. Unfortunately it seems that there is
|
||||
* no secure mode using AES.
|
||||
*/
|
||||
@SuppressWarnings("InsecureCipherMode")
|
||||
public void testDhiesBasic() throws Exception {
|
||||
DHParameterSpec params = ike2048();
|
||||
KeyPairGenerator kf = KeyPairGenerator.getInstance("DH");
|
||||
kf.initialize(params);
|
||||
KeyPair keyPair = kf.generateKeyPair();
|
||||
PrivateKey priv = keyPair.getPrivate();
|
||||
PublicKey pub = keyPair.getPublic();
|
||||
byte[] message = "Hello".getBytes("UTF-8");
|
||||
Cipher dhies = Cipher.getInstance("DHIESwithAES");
|
||||
dhies.init(Cipher.ENCRYPT_MODE, pub);
|
||||
byte[] ciphertext = dhies.doFinal(message);
|
||||
System.out.println("testDhiesBasic:" + TestUtil.bytesToHex(ciphertext));
|
||||
dhies.init(Cipher.DECRYPT_MODE, priv);
|
||||
byte[] decrypted = dhies.doFinal(ciphertext);
|
||||
assertEquals(TestUtil.bytesToHex(message), TestUtil.bytesToHex(decrypted));
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: This test uses weak crypto (i.e. DHIESWithAES). DHIES should be secure against chosen
|
||||
* ciphertexts. Checks that a modification of the ciphertext is dectected.
|
||||
*/
|
||||
@SlowTest(providers = {ProviderType.BOUNCY_CASTLE, ProviderType.SPONGY_CASTLE})
|
||||
@SuppressWarnings("InsecureCipherMode")
|
||||
public void testDhiesCorrupt() throws Exception {
|
||||
KeyPairGenerator kf = KeyPairGenerator.getInstance("DH");
|
||||
kf.initialize(ike2048());
|
||||
KeyPair keyPair = kf.generateKeyPair();
|
||||
PrivateKey priv = keyPair.getPrivate();
|
||||
PublicKey pub = keyPair.getPublic();
|
||||
byte[] message = new byte[32];
|
||||
Cipher dhies = Cipher.getInstance("DHIESwithAES");
|
||||
dhies.init(Cipher.ENCRYPT_MODE, pub);
|
||||
byte[] ciphertext = dhies.doFinal(message);
|
||||
for (int i = 0; i < ciphertext.length; i++) {
|
||||
byte[] corrupt = Arrays.copyOf(ciphertext, ciphertext.length);
|
||||
corrupt[i] ^= (byte) 1;
|
||||
try {
|
||||
dhies.init(Cipher.DECRYPT_MODE, priv);
|
||||
dhies.doFinal(corrupt);
|
||||
fail("Corrupt ciphertext accepted:" + i);
|
||||
} catch (GeneralSecurityException ex) {
|
||||
// This is expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to detect if an algorithm is using ECB. Unfortunately, many JCE algorithms use ECB if no
|
||||
* encryption mode is specified.
|
||||
*/
|
||||
@SuppressWarnings("InsecureCipherMode")
|
||||
public void testNotEcb(String algorithm) throws Exception {
|
||||
Cipher dhies;
|
||||
try {
|
||||
dhies = Cipher.getInstance(algorithm);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
// This test is called with short algorithm names such as just "DHIES".
|
||||
// Requiring full names is typically a good practice. Hence it is OK
|
||||
// to not assigning default algorithms.
|
||||
System.out.println("No implementation for:" + algorithm);
|
||||
return;
|
||||
}
|
||||
KeyPairGenerator kf = KeyPairGenerator.getInstance("DH");
|
||||
kf.initialize(ike2048());
|
||||
KeyPair keyPair = kf.generateKeyPair();
|
||||
PublicKey pub = keyPair.getPublic();
|
||||
byte[] message = new byte[512];
|
||||
dhies.init(Cipher.ENCRYPT_MODE, pub);
|
||||
byte[] ciphertext = dhies.doFinal(message);
|
||||
for (int i = 0; i + 32 <= ciphertext.length; i++) {
|
||||
String block1 = TestUtil.bytesToHex(Arrays.copyOfRange(ciphertext, i, i + 16));
|
||||
String block2 = TestUtil.bytesToHex(Arrays.copyOfRange(ciphertext, i + 16, i + 32));
|
||||
assertTrue(
|
||||
"Ciphertext repeats at " + i + ":" + TestUtil.bytesToHex(ciphertext),
|
||||
!block1.equals(block2));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSemanticSecurityDhies() throws Exception {
|
||||
testNotEcb("DHIES");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user