All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.open.jwtdependency.org.bouncycastle.crypto.test.SRP6Test Maven / Gradle / Ivy

Go to download

This is a drop in replacement for the auth0 java-jwt library (see https://github.com/auth0/java-jwt). This jar makes sure there are no external dependencies (e.g. fasterXml, Apacha Commons) needed. This is useful when deploying to an application server (e.g. tomcat with Alfreso or Pega).

The newest version!
package org.bouncycastle.crypto.test;

import java.math.BigInteger;
import java.security.SecureRandom;

import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.agreement.srp.SRP6Client;
import org.bouncycastle.crypto.agreement.srp.SRP6Server;
import org.bouncycastle.crypto.agreement.srp.SRP6StandardGroups;
import org.bouncycastle.crypto.agreement.srp.SRP6Util;
import org.bouncycastle.crypto.agreement.srp.SRP6VerifierGenerator;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.generators.DHParametersGenerator;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.crypto.params.SRP6GroupParameters;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;

public class SRP6Test extends SimpleTest
{
    private static final BigInteger ZERO = BigInteger.valueOf(0);

    private static BigInteger fromHex(String hex)
    {
        return new BigInteger(1, Hex.decode(hex));
    }

    private final SecureRandom random = new SecureRandom();

    public String getName()
    {
        return "SRP6";
    }

    public void performTest() throws Exception
    {
        rfc5054AppendixBTestVectors();

        testMutualVerification(SRP6StandardGroups.rfc5054_1024);
        testClientCatchesBadB(SRP6StandardGroups.rfc5054_1024);
        testServerCatchesBadA(SRP6StandardGroups.rfc5054_1024);

        testWithRandomParams(256);
        testWithRandomParams(384);
        testWithRandomParams(512);
    }

    private void rfc5054AppendixBTestVectors() throws Exception
    {
        byte[] I = "alice".getBytes("UTF8");
        byte[] P = "password123".getBytes("UTF8");
        byte[] s = Hex.decode("BEB25379D1A8581EB5A727673A2441EE");
        BigInteger N = SRP6StandardGroups.rfc5054_1024.getN();
        BigInteger g = SRP6StandardGroups.rfc5054_1024.getG();
        BigInteger a = fromHex("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393");
        BigInteger b = fromHex("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D105284D20");

        BigInteger expect_k = fromHex("7556AA045AEF2CDD07ABAF0F665C3E818913186F");
        BigInteger expect_x = fromHex("94B7555AABE9127CC58CCF4993DB6CF84D16C124");
        BigInteger expect_v = fromHex("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812"
            + "9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5"
            + "C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5"
            + "EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78"
            + "E955A5E29E7AB245DB2BE315E2099AFB");
        BigInteger expect_A = fromHex("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
            + "4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC"
            + "8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44"
            + "BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA"
            + "B349EF5D76988A3672FAC47B0769447B");
        BigInteger expect_B = fromHex("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
            + "BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99"
            + "6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA"
            + "37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE"
            + "EB4012B7D7665238A8E3FB004B117B58");
        BigInteger expect_u = fromHex("CE38B9593487DA98554ED47D70A7AE5F462EF019");
        BigInteger expect_S = fromHex("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
            + "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
            + "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
            + "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
            + "C346D7E474B29EDE8A469FFECA686E5A");

        BigInteger k = SRP6Util.calculateK(new SHA1Digest(), N, g);
        if (!k.equals(expect_k))
        {
            fail("wrong value of 'k'");
        }

        BigInteger x = SRP6Util.calculateX(new SHA1Digest(), N, s, I, P);
        if (!x.equals(expect_x))
        {
            fail("wrong value of 'x'");
        }

        SRP6VerifierGenerator gen = new SRP6VerifierGenerator();
        gen.init(N, g, new SHA1Digest());
        BigInteger v = gen.generateVerifier(s, I, P);
        if (!v.equals(expect_v))
        {
            fail("wrong value of 'v'");
        }

        final BigInteger aVal = a;
        SRP6Client client = new SRP6Client()
        {
            protected BigInteger selectPrivateValue()
            {
                return aVal;
            }
        };
        client.init(N, g, new SHA1Digest(), random);

        BigInteger A = client.generateClientCredentials(s, I, P);
        if (!A.equals(expect_A))
        {
            fail("wrong value of 'A'");
        }

        final BigInteger bVal = b;
        SRP6Server server = new SRP6Server()
        {
            protected BigInteger selectPrivateValue()
            {
                return bVal;
            }
        };
        server.init(N, g, v, new SHA1Digest(), random);

        BigInteger B = server.generateServerCredentials();
        if (!B.equals(expect_B))
        {
            fail("wrong value of 'B'");
        }

        BigInteger u = SRP6Util.calculateU(new SHA1Digest(), N, A, B);
        if (!u.equals(expect_u))
        {
            fail("wrong value of 'u'");
        }

        BigInteger clientS = client.calculateSecret(B);
        if (!clientS.equals(expect_S))
        {
            fail("wrong value of 'S' (client)");
        }

        BigInteger serverS = server.calculateSecret(A);
        if (!serverS.equals(expect_S))
        {
            fail("wrong value of 'S' (server)");
        }
    }

    private void testWithRandomParams(int bits) throws CryptoException
    {
        DHParametersGenerator paramGen = new DHParametersGenerator();
        paramGen.init(bits, 25, random);
        DHParameters parameters = paramGen.generateParameters();

        testMutualVerification(new SRP6GroupParameters(parameters.getP(), parameters.getG()));
    }

    private void testMutualVerification(SRP6GroupParameters group) throws CryptoException
    {
        byte[] I = "username".getBytes();
        byte[] P = "password".getBytes();
        byte[] s = new byte[16];
        random.nextBytes(s);

        SRP6VerifierGenerator gen = new SRP6VerifierGenerator();
        gen.init(group, new SHA256Digest());
        BigInteger v = gen.generateVerifier(s, I, P);

        SRP6Client client = new SRP6Client();
        client.init(group, new SHA256Digest(), random);

        SRP6Server server = new SRP6Server();
        server.init(group, v, new SHA256Digest(), random);

        BigInteger A = client.generateClientCredentials(s, I, P);
        BigInteger B = server.generateServerCredentials();

        BigInteger clientS = client.calculateSecret(B);
        BigInteger serverS = server.calculateSecret(A);

        if (!clientS.equals(serverS))
        {
            fail("SRP agreement failed - client/server calculated different secrets");
        }
    }

    private void testClientCatchesBadB(SRP6GroupParameters group)
    {
        byte[] I = "username".getBytes();
        byte[] P = "password".getBytes();
        byte[] s = new byte[16];
        random.nextBytes(s);

        SRP6Client client = new SRP6Client();
        client.init(group, new SHA256Digest(), random);

        client.generateClientCredentials(s, I, P);

        try
        {
            client.calculateSecret(ZERO);
            fail("Client failed to detect invalid value for 'B'");
        }
        catch (CryptoException e)
        {
            // Expected
        }

        try
        {
            client.calculateSecret(group.getN());
            fail("Client failed to detect invalid value for 'B'");
        }
        catch (CryptoException e)
        {
            // Expected
        }
    }

    private void testServerCatchesBadA(SRP6GroupParameters group)
    {
        byte[] I = "username".getBytes();
        byte[] P = "password".getBytes();
        byte[] s = new byte[16];
        random.nextBytes(s);

        SRP6VerifierGenerator gen = new SRP6VerifierGenerator();
        gen.init(group, new SHA256Digest());
        BigInteger v = gen.generateVerifier(s, I, P);

        SRP6Server server = new SRP6Server();
        server.init(group, v, new SHA256Digest(), random);

        server.generateServerCredentials();

        try
        {
            server.calculateSecret(ZERO);
            fail("Client failed to detect invalid value for 'A'");
        }
        catch (CryptoException e)
        {
            // Expected
        }

        try
        {
            server.calculateSecret(group.getN());
            fail("Client failed to detect invalid value for 'A'");
        }
        catch (CryptoException e)
        {
            // Expected
        }
    }

    public static void main(String[] args)
    {
        runTest(new SRP6Test());
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy