Search in sources :

Example 6 with Signature

use of java.security.Signature in project platform_frameworks_base by android.

the class CertPinInstallReceiverTest method createSignature.

private String createSignature(String content, String version, String requiredHash) throws Exception {
    Signature signer = Signature.getInstance("SHA512withRSA");
    signer.initSign(createKey());
    signer.update(content.trim().getBytes());
    signer.update(version.trim().getBytes());
    signer.update(requiredHash.getBytes());
    String sig = new String(Base64.encode(signer.sign(), Base64.DEFAULT));
    assertEquals(true, verifySignature(content, version, requiredHash, sig, createCertificate()));
    return sig;
}
Also used : Signature(java.security.Signature)

Example 7 with Signature

use of java.security.Signature in project wycheproof by google.

the class DsaTest method testBiasSha1WithDSA.

/**
   * Checks whether CVE-2016-0695 has been fixed. Before the April 2016 security update, the SUN
   * provider had a serious flaw that leaked the private key with about 3-5 signatures. In
   * particular, "Sha1WithDSA" always generated 160 bit k's independently of q. Unfortunately, it is
   * easily possible to use 2048 and 3072 bit DSA keys together with SHA1WithDSA. All a user has to
   * do is to use the algorithm name "DSA" instead of "SHA256WithDSA" rsp. "SHA224WithDSA".
   *
   * <p>An algorithm to extract the key from the signatures has been described for example in the
   * paper <a href="http://www.hpl.hp.com/techreports/1999/HPL-1999-90.pdf">Lattice Attacks on
   * Digital Signature Schemes</a> by N.A. Howgrave-Graham, N.P. Smart.
   *
   * <p>This bug is the same as US-CERT: VU # 940388: GnuPG generated ElGamal signatures that leaked
   * the private key.
   */
@SlowTest(providers = { ProviderType.BOUNCY_CASTLE, ProviderType.SPONGY_CASTLE })
@SuppressWarnings("InsecureCryptoUsage")
public void testBiasSha1WithDSA() throws Exception {
    String hashAlgorithm = "SHA";
    String message = "Hello";
    byte[] messageBytes = message.getBytes("UTF-8");
    byte[] digest = MessageDigest.getInstance(hashAlgorithm).digest(messageBytes);
    BigInteger h = new BigInteger(1, digest);
    KeyPairGenerator generator = java.security.KeyPairGenerator.getInstance("DSA");
    generator.initialize(2048);
    KeyPair keyPair = generator.generateKeyPair();
    DSAPrivateKey priv = (DSAPrivateKey) keyPair.getPrivate();
    Signature signer = Signature.getInstance("DSA");
    try {
        // Private key and selected algorithm by signer do not match.
        // Hence throwing an exception at this point would be the reasonable.
        signer.initSign(priv);
        signer.update(messageBytes);
        byte[] signature = signer.sign();
        BigInteger q = priv.getParams().getQ();
        BigInteger k = extractK(signature, h, priv, true);
        // Now check if k is heavily biased.
        int lengthDiff = q.bitLength() - k.bitLength();
        if (lengthDiff > 32) {
            fail("Severly biased DSA signature:" + " len(q)=" + q.bitLength() + " len(k)=" + k.bitLength());
        }
    } catch (GeneralSecurityException ex) {
        // The key is invalid, hence getting here is reasonable.
        return;
    }
}
Also used : KeyPair(java.security.KeyPair) Signature(java.security.Signature) GeneralSecurityException(java.security.GeneralSecurityException) BigInteger(java.math.BigInteger) DSAPrivateKey(java.security.interfaces.DSAPrivateKey) KeyPairGenerator(java.security.KeyPairGenerator) SlowTest(com.google.security.wycheproof.WycheproofRunner.SlowTest)

Example 8 with Signature

use of java.security.Signature in project wycheproof by google.

the class DsaTest method testTiming.

/**
   * This test checks for potential of a timing attack. The test generates a number of signatures,
   * selects a fraction of them with a small timing and then compares the values k for the selected
   * signatures with a normal distribution. The test fails if these ks are much smaller than
   * expected. An implementation flaw that can lead to a test failure is to compute the signature
   * with a modular exponentiation with a runtime that depend on the length of the exponent.
   *
   * <p>A failing test simply means that the timing can be used to get information about k. Further
   * analysis is necessary to determine if the bias is exploitable and how many timings are
   * necessary for an attack. A passing test does not mean that the implementation is secure against
   * timing attacks. The test only catches relatively big timing differences. It requires high
   * confidence to fail. Noise on the test machine can prevent that a relation between timing and k
   * can be detected.
   *
   * <p>Claims of what is exploitable: http://www.hpl.hp.com/techreports/1999/HPL-1999-90.pdf 30
   * signatures are sufficient to find the private key if the attacker knows 8 bits of each k.
   * http://eprint.iacr.org/2004/277.pdf 27 signatures are sufficient if 8 bits of each k is known.
   * Our own old experiments (using 1GB memory on a Pentium-4? CPU): 2^11 signatures are sufficient
   * with a 3 bit leakage. 2^15 signatures are sufficient with a 2 bit leakage. 2^24 signatures are
   * sufficient with a 1 bit leakage. Estimate for biased generation in the NIST standard: e.g. 2^22
   * signatures, 2^40 memory, 2^64 time
   *
   * <p><b>Sample output for the SUN provider:</b> <code>
   * count:50000 cutoff:4629300 relative average:0.9992225872624547 sigmas:0.3010906585642381
   * count:25000 cutoff:733961 relative average:0.976146066585879 sigmas:6.532668708070148
   * count:12500 cutoff:688305 relative average:0.9070352192339134 sigmas:18.00255238454385
   * count:6251 cutoff:673971 relative average:0.7747148791368986 sigmas:30.850903417893825
   * count:3125 cutoff:667045 relative average:0.5901994097874541 sigmas:39.67877152897901
   * count:1563 cutoff:662088 relative average:0.4060286694971057 sigmas:40.67294313795137
   * count:782 cutoff:657921 relative average:0.2577955312387898 sigmas:35.94906247333319
   * count:391 cutoff:653608 relative average:0.1453438859272699 sigmas:29.271192100879457
   * count:196 cutoff:649280 relative average:0.08035497211567771 sigmas:22.300206785132406
   * count:98 cutoff:645122 relative average:0.05063589092661368 sigmas:16.27820353139225
   * count:49 cutoff:641582 relative average:0.018255560447883384 sigmas:11.903018745467488
   * count:25 cutoff:638235 relative average:0.009082660721102722 sigmas:8.581595888660086
   * count:13 cutoff:633975 relative average:0.0067892346039088326 sigmas:6.20259924188633
   * </code>
   *
   * <p><b>What this shows:</b> The first line uses all 50'000 signatures. The average k of these
   * signatures is close to the expected value q/2. Being more selective gives us signatures with a
   * more biased k. For example, the 196 signatures with the fastest timing have about a 3-bit bias.
   * From this we expect that 2^19 signatures and timings are sufficient to find the private key.
   *
   * <p>A list of problems caught by this test:
   * <ul>
   * <li> CVE-2016-5548 OpenJDK8's DSA is vulnerable to timing attacks.
   * <li> CVE-2016-1000341 BouncyCastle before v 1.56 is vulnernerable to timing attacks.
   * </ul>
   */
@SlowTest(providers = { ProviderType.BOUNCY_CASTLE, ProviderType.OPENJDK, ProviderType.SPONGY_CASTLE })
@SuppressWarnings("InsecureCryptoUsage")
public void testTiming() throws Exception {
    ThreadMXBean bean = ManagementFactory.getThreadMXBean();
    if (!bean.isCurrentThreadCpuTimeSupported()) {
        System.out.println("getCurrentThreadCpuTime is not supported. Skipping");
        return;
    }
    String hashAlgorithm = "SHA-1";
    String message = "Hello";
    byte[] messageBytes = message.getBytes("UTF-8");
    byte[] digest = MessageDigest.getInstance(hashAlgorithm).digest(messageBytes);
    BigInteger h = new BigInteger(1, digest);
    KeyPairGenerator generator = java.security.KeyPairGenerator.getInstance("DSA");
    generator.initialize(1024);
    KeyPair keyPair = generator.generateKeyPair();
    DSAPrivateKey priv = (DSAPrivateKey) keyPair.getPrivate();
    Signature signer = Signature.getInstance("SHA1WITHDSA");
    signer.initSign(priv);
    // The timings below are quite noisy. Thus we need a large number of samples.
    int samples = 50000;
    long[] timing = new long[samples];
    BigInteger[] k = new BigInteger[samples];
    for (int i = 0; i < samples; i++) {
        long start = bean.getCurrentThreadCpuTime();
        signer.update(messageBytes);
        byte[] signature = signer.sign();
        timing[i] = bean.getCurrentThreadCpuTime() - start;
        k[i] = extractK(signature, h, priv, false);
    }
    long[] sorted = Arrays.copyOf(timing, timing.length);
    Arrays.sort(sorted);
    // Here we are only interested in roughly the 8 most significant bits of the ks.
    // Hence, using double is sufficiently precise.
    double q = priv.getParams().getQ().doubleValue();
    double expectedAverage = q / 2;
    double maxSigmas = 0;
    System.out.println("testTiming: SHA1WITHDSA");
    for (int idx = samples - 1; idx > 10; idx /= 2) {
        long cutoff = sorted[idx];
        int count = 0;
        double total = 0;
        for (int i = 0; i < samples; i++) {
            if (timing[i] <= cutoff) {
                total += k[i].doubleValue();
                count += 1;
            }
        }
        double expectedStdDev = q / Math.sqrt(12 * count);
        double average = total / count;
        // Number of standard deviations that the average is away from
        // the expected value:
        double sigmas = (expectedAverage - average) / expectedStdDev;
        if (sigmas > maxSigmas) {
            maxSigmas = sigmas;
        }
        System.out.println("count:" + count + " cutoff:" + cutoff + " relative average:" + (average / expectedAverage) + " sigmas:" + sigmas);
    }
    // than 10^{-10}.
    if (maxSigmas >= 7) {
        fail("Signatures with short timing have a biased k");
    }
}
Also used : ThreadMXBean(java.lang.management.ThreadMXBean) KeyPair(java.security.KeyPair) KeyPairGenerator(java.security.KeyPairGenerator) Signature(java.security.Signature) BigInteger(java.math.BigInteger) DSAPrivateKey(java.security.interfaces.DSAPrivateKey) SlowTest(com.google.security.wycheproof.WycheproofRunner.SlowTest)

Example 9 with Signature

use of java.security.Signature in project wycheproof by google.

the class RsaSignatureTest method testVectors.

/**
   * Tests an RSA signature implementation with a number of vectors. The test assumes that the first
   * test vector is valid, but everything else is invalid. Many of the test vectors are derived by
   * signing modified ASN encodings. Hence accepting an invalid signature does not mean by itself
   * that the implementation can be broken, but often points to a bigger problem. The test expects
   * that verifying an invalid signature either leads to a return value False or will result in a
   * SignatureException. Verifying an RSA signature should not result in an RuntimeException, so
   * that reasonably implementated applications can be expected to catch and treat invalid
   * signatures appropriately. While RuntimeExceptions may not be exploitable, they often indicate 
   * an oversight in the implementation of the provider.
   * https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
   */
public void testVectors(RSAPublicKeySpec key, String algorithm, String[] testvectors) throws Exception {
    byte[] message = "Test".getBytes("UTF-8");
    Signature verifier = Signature.getInstance(algorithm);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pub = kf.generatePublic(key);
    int errors = 0;
    boolean first = true;
    for (String signature : testvectors) {
        byte[] signatureBytes = TestUtil.hexToBytes(signature);
        verifier.initVerify(pub);
        verifier.update(message);
        boolean verified = false;
        try {
            verified = verifier.verify(signatureBytes);
        } catch (SignatureException ex) {
        // verify can throw SignatureExceptions if the signature is malformed.
        }
        if (first && !verified) {
            System.out.println("Valid signature not verified:" + signature);
            errors++;
        } else if (!first && verified) {
            System.out.println("Incorrect signature verified:" + signature);
            errors++;
        }
        first = false;
    }
    assertEquals(0, errors);
}
Also used : RSAPublicKey(java.security.interfaces.RSAPublicKey) PublicKey(java.security.PublicKey) Signature(java.security.Signature) SignatureException(java.security.SignatureException) KeyFactory(java.security.KeyFactory)

Example 10 with Signature

use of java.security.Signature in project wycheproof by google.

the class RsaSignatureTest method testBasic.

public void testBasic() throws Exception {
    String algorithm = "SHA256WithRSA";
    String hashAlgorithm = "SHA-256";
    String message = "Hello";
    int keysize = 2048;
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
    keyGen.initialize(keysize);
    KeyPair keyPair = keyGen.generateKeyPair();
    RSAPublicKey pub = (RSAPublicKey) keyPair.getPublic();
    RSAPrivateKey priv = (RSAPrivateKey) keyPair.getPrivate();
    byte[] messageBytes = message.getBytes("UTF-8");
    Signature signer = Signature.getInstance(algorithm);
    Signature verifier = Signature.getInstance(algorithm);
    signer.initSign(priv);
    signer.update(messageBytes);
    byte[] signature = signer.sign();
    verifier.initVerify(pub);
    verifier.update(messageBytes);
    assertTrue(verifier.verify(signature));
    // Extract some parameters.
    byte[] rawHash = MessageDigest.getInstance(hashAlgorithm).digest(messageBytes);
    // Print keys and signature, so that it can be used to generate new test vectors.
    System.out.println("Message:" + message);
    System.out.println("Hash:" + TestUtil.bytesToHex(rawHash));
    System.out.println("Public key:");
    System.out.println("Modulus:" + pub.getModulus().toString());
    System.out.println("E:" + pub.getPublicExponent().toString());
    System.out.println("encoded:" + TestUtil.bytesToHex(pub.getEncoded()));
    System.out.println("Private key:");
    System.out.println("D:" + priv.getPrivateExponent().toString());
    System.out.println("encoded:" + TestUtil.bytesToHex(priv.getEncoded()));
    System.out.println("Signature:" + TestUtil.bytesToHex(signature));
}
Also used : KeyPair(java.security.KeyPair) RSAPublicKey(java.security.interfaces.RSAPublicKey) Signature(java.security.Signature) KeyPairGenerator(java.security.KeyPairGenerator) RSAPrivateKey(java.security.interfaces.RSAPrivateKey)

Aggregations

Signature (java.security.Signature)261 SignatureException (java.security.SignatureException)84 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)70 InvalidKeyException (java.security.InvalidKeyException)61 PublicKey (java.security.PublicKey)61 PrivateKey (java.security.PrivateKey)43 IOException (java.io.IOException)42 KeyFactory (java.security.KeyFactory)41 X509Certificate (java.security.cert.X509Certificate)26 RSAPublicKeySpec (java.security.spec.RSAPublicKeySpec)23 KeyPair (java.security.KeyPair)19 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)19 GeneralSecurityException (java.security.GeneralSecurityException)16 KeyPairGenerator (java.security.KeyPairGenerator)16 MySignature1 (org.apache.harmony.security.tests.support.MySignature1)16 ByteArrayInputStream (java.io.ByteArrayInputStream)14 BigInteger (java.math.BigInteger)14 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)14 CertificateException (java.security.cert.CertificateException)14 X509EncodedKeySpec (java.security.spec.X509EncodedKeySpec)14