private void checkKeySize(int privateValueSize, KeyPair aKeyPair) {
    if (privateValueSize != 0) {
      DHPrivateKey key = (DHPrivateKey) aKeyPair.getPrivate();

      if (key.getX().bitLength() != privateValueSize) {
        fail("limited key check failed for key size " + privateValueSize);
      }
    }
  }
Exemple #2
0
  protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
    if (!(key instanceof DHPrivateKey)) {
      throw new InvalidKeyException("DHKeyAgreement requires DHPrivateKey");
    }

    DHPrivateKey privKey = (DHPrivateKey) key;

    this.p = privKey.getParams().getP();
    this.g = privKey.getParams().getG();
    this.x = this.result = privKey.getX();
  }
  protected int engineGetKeySize(Key key) {
    if (!(key instanceof IESKey)) {
      throw new IllegalArgumentException("must be passed IE key");
    }

    IESKey ieKey = (IESKey) key;

    if (ieKey.getPrivate() instanceof DHPrivateKey) {
      DHPrivateKey k = (DHPrivateKey) ieKey.getPrivate();

      return k.getX().bitLength();
    } else if (ieKey.getPrivate() instanceof ECPrivateKey) {
      ECPrivateKey k = (ECPrivateKey) ieKey.getPrivate();

      return k.getD().bitLength();
    }

    throw new IllegalArgumentException("not an IE key!");
  }
  /** Given a DH key pair, return the BIND9-style text encoding */
  private String generatePrivateDH(DHPrivateKey key, DHPublicKey pub, int algorithm) {
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();

    DHParameterSpec p = key.getParams();

    out.println("Private-key-format: v1.2");
    out.println("Algorithm: " + algorithm + " (" + algs.algToString(algorithm) + ")");
    out.print("Prime(p): ");
    out.println(b64BigInt(p.getP()));
    out.print("Generator(g): ");
    out.println(b64BigInt(p.getG()));
    out.print("Private_value(x): ");
    out.println(b64BigInt(key.getX()));
    out.print("Public_value(y): ");
    out.println(b64BigInt(pub.getY()));

    return sw.toString();
  }
Exemple #5
0
  protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
      throws InvalidKeyException, InvalidAlgorithmParameterException {
    if (!(key instanceof DHPrivateKey)) {
      throw new InvalidKeyException("DHKeyAgreement requires DHPrivateKey for initialisation");
    }
    DHPrivateKey privKey = (DHPrivateKey) key;

    if (params != null) {
      if (!(params instanceof DHParameterSpec)) {
        throw new InvalidAlgorithmParameterException("DHKeyAgreement only accepts DHParameterSpec");
      }
      DHParameterSpec p = (DHParameterSpec) params;

      this.p = p.getP();
      this.g = p.getG();
    } else {
      this.p = privKey.getParams().getP();
      this.g = privKey.getParams().getG();
    }

    this.x = this.result = privKey.getX();
  }
  protected KeySpec engineGetKeySpec(Key key, Class spec) throws InvalidKeySpecException {
    if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8")) {
      return new PKCS8EncodedKeySpec(key.getEncoded());
    } else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509")) {
      return new X509EncodedKeySpec(key.getEncoded());
    } else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey) {
      RSAPublicKey k = (RSAPublicKey) key;

      return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
    } else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey) {
      RSAPrivateKey k = (RSAPrivateKey) key;

      return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
    } else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class)
        && key instanceof RSAPrivateCrtKey) {
      RSAPrivateCrtKey k = (RSAPrivateCrtKey) key;

      return new RSAPrivateCrtKeySpec(
          k.getModulus(),
          k.getPublicExponent(),
          k.getPrivateExponent(),
          k.getPrimeP(),
          k.getPrimeQ(),
          k.getPrimeExponentP(),
          k.getPrimeExponentQ(),
          k.getCrtCoefficient());
    } else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey) {
      DHPrivateKey k = (DHPrivateKey) key;

      return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
    } else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey) {
      DHPublicKey k = (DHPublicKey) key;

      return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
    }

    throw new RuntimeException("not implemented yet " + key + " " + spec);
  }
  private void testGP(int size, int privateValueSize, BigInteger g, BigInteger p) throws Exception {
    DHParameterSpec elParams = new DHParameterSpec(p, g, privateValueSize);
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC");
    byte[] in = "This is a test".getBytes();

    keyGen.initialize(elParams);

    KeyPair keyPair = keyGen.generateKeyPair();
    SecureRandom rand = new SecureRandom();

    checkKeySize(privateValueSize, keyPair);

    Cipher cipher = Cipher.getInstance("ElGamal", "BC");

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    if (cipher.getOutputSize(in.length) != (size / 8) * 2) {
      fail("getOutputSize wrong on encryption");
    }

    byte[] out = cipher.doFinal(in);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    if (cipher.getOutputSize(out.length) != (size / 8) - 1) {
      fail("getOutputSize wrong on decryption");
    }

    //
    // No Padding - maximum length
    //
    byte[] modBytes = ((DHPublicKey) keyPair.getPublic()).getParams().getP().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    out = cipher.doFinal(maxInput);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    out = cipher.doFinal(out);

    if (!areEqual(out, maxInput)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(maxInput))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // encrypt/decrypt
    //

    Cipher c1 = Cipher.getInstance("ElGamal", "BC");
    Cipher c2 = Cipher.getInstance("ElGamal", "BC");

    c1.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    byte[] out1 = c1.doFinal(in);

    c2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    byte[] out2 = c2.doFinal(out1);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt test failed");
    }

    //
    // encrypt/decrypt with update
    //
    int outLen = c1.update(in, 0, 2, out1, 0);

    outLen += c1.doFinal(in, 2, in.length - 2, out1, outLen);

    outLen = c2.update(out1, 0, 2, out2, 0);

    outLen += c2.doFinal(out1, 2, out1.length - 2, out2, outLen);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt with update test failed");
    }

    //
    // public key encoding test
    //
    byte[] pubEnc = keyPair.getPublic().getEncoded();
    KeyFactory keyFac = KeyFactory.getInstance("ElGamal", "BC");
    X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
    DHPublicKey pubKey = (DHPublicKey) keyFac.generatePublic(pubX509);
    DHParameterSpec spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key encoding/decoding test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key encoding/decoding test failed on y value");
    }

    //
    // public key serialisation test
    //
    pubKey = (DHPublicKey) serializeDeserialize(keyPair.getPublic());
    spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key serialisation test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key serialisation test failed on y value");
    }

    if (!keyPair.getPublic().equals(pubKey)) {
      fail("equals test failed");
    }

    if (keyPair.getPublic().hashCode() != pubKey.hashCode()) {
      fail("hashCode test failed");
    }

    //
    // private key encoding test
    //
    byte[] privEnc = keyPair.getPrivate().getEncoded();
    PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
    DHPrivateKey privKey = (DHPrivateKey) keyFac.generatePrivate(privPKCS8);

    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key encoding/decoding test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key encoding/decoding test failed on y value");
    }

    //
    // private key serialisation test
    //
    privKey = (DHPrivateKey) serializeDeserialize(keyPair.getPrivate());
    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key serialisation test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key serialisation test failed on y value");
    }

    if (!keyPair.getPrivate().equals(privKey)) {
      fail("equals test failed");
    }

    if (keyPair.getPrivate().hashCode() != privKey.hashCode()) {
      fail("hashCode test failed");
    }

    if (!(privKey instanceof PKCS12BagAttributeCarrier)) {
      fail("private key not implementing PKCS12 attribute carrier");
    }
  }
  private void testDefault(int privateValueSize, BigInteger g, BigInteger p) throws Exception {
    DHParameterSpec elParams = new DHParameterSpec(p, g, privateValueSize);
    int size = p.bitLength();

    new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, elParams);

    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC");
    byte[] in = "This is a test".getBytes();

    keyGen.initialize(p.bitLength());

    KeyPair keyPair = keyGen.generateKeyPair();

    new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, elParams);

    SecureRandom rand = new SecureRandom();

    checkKeySize(privateValueSize, keyPair);

    Cipher cipher = Cipher.getInstance("ElGamal", "BC");

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    if (cipher.getOutputSize(in.length) != (size / 8) * 2) {
      fail("getOutputSize wrong on encryption");
    }

    byte[] out = cipher.doFinal(in);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    if (cipher.getOutputSize(out.length) != (size / 8) - 1) {
      fail("getOutputSize wrong on decryption");
    }

    //
    // No Padding - maximum length
    //
    byte[] modBytes = ((DHPublicKey) keyPair.getPublic()).getParams().getP().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    out = cipher.doFinal(maxInput);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    out = cipher.doFinal(out);

    if (!areEqual(out, maxInput)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(maxInput))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // encrypt/decrypt
    //

    Cipher c1 = Cipher.getInstance("ElGamal", "BC");
    Cipher c2 = Cipher.getInstance("ElGamal", "BC");

    c1.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    byte[] out1 = c1.doFinal(in);

    c2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    byte[] out2 = c2.doFinal(out1);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt test failed");
    }

    //
    // encrypt/decrypt with update
    //
    int outLen = c1.update(in, 0, 2, out1, 0);

    outLen += c1.doFinal(in, 2, in.length - 2, out1, outLen);

    outLen = c2.update(out1, 0, 2, out2, 0);

    outLen += c2.doFinal(out1, 2, out1.length - 2, out2, outLen);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt with update test failed");
    }

    //
    // public key encoding test
    //
    byte[] pubEnc = keyPair.getPublic().getEncoded();
    KeyFactory keyFac = KeyFactory.getInstance("ElGamal", "BC");
    X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
    DHPublicKey pubKey = (DHPublicKey) keyFac.generatePublic(pubX509);
    DHParameterSpec spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key encoding/decoding test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key encoding/decoding test failed on y value");
    }

    //
    // public key serialisation test
    //
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ObjectOutputStream oOut = new ObjectOutputStream(bOut);

    oOut.writeObject(keyPair.getPublic());

    ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
    ObjectInputStream oIn = new ObjectInputStream(bIn);

    pubKey = (DHPublicKey) oIn.readObject();
    spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key serialisation test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key serialisation test failed on y value");
    }

    //
    // private key encoding test
    //
    byte[] privEnc = keyPair.getPrivate().getEncoded();
    PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
    DHPrivateKey privKey = (DHPrivateKey) keyFac.generatePrivate(privPKCS8);

    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key encoding/decoding test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key encoding/decoding test failed on y value");
    }

    //
    // private key serialisation test
    //
    bOut = new ByteArrayOutputStream();
    oOut = new ObjectOutputStream(bOut);

    oOut.writeObject(keyPair.getPrivate());

    bIn = new ByteArrayInputStream(bOut.toByteArray());
    oIn = new ObjectInputStream(bIn);

    privKey = (DHPrivateKey) oIn.readObject();
    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key serialisation test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key serialisation test failed on y value");
    }
  }
Exemple #9
0
  private StringBuffer outputKeyCreation(int loop, boolean kekOnly, String kekTest) {
    StringBuffer buf = new StringBuffer();
    loop++;

    if (loop > 100) {
      // only loop 100 times; then throw an exception
      throw new IllegalStateException("Unable to create 128 byte keys in 100 tries");
    }

    // place holder for the keys
    DHPrivateKey privateKey = null;
    DHPublicKey publicKey = null;

    if (!kekOnly) {
      KeyPair keyPair = null;
      try {
        keyPair = this.createKeys();
      } catch (NoSuchAlgorithmException e) {
        Debug.logError(e, module);
      } catch (InvalidAlgorithmParameterException e) {
        Debug.logError(e, module);
      } catch (InvalidKeySpecException e) {
        Debug.logError(e, module);
      }

      if (keyPair != null) {
        publicKey = (DHPublicKey) keyPair.getPublic();
        privateKey = (DHPrivateKey) keyPair.getPrivate();

        if (publicKey == null || publicKey.getY().toByteArray().length != 128) {
          // run again until we get a 128 byte public key for VL
          return this.outputKeyCreation(loop, kekOnly, kekTest);
        }
      } else {
        Debug.logInfo("Returned a null KeyPair", module);
        return this.outputKeyCreation(loop, kekOnly, kekTest);
      }
    } else {
      // use our existing private key to generate a KEK
      try {
        privateKey = (DHPrivateKey) this.getPrivateKey();
      } catch (Exception e) {
        Debug.logError(e, module);
      }
    }

    // the KEK
    byte[] kekBytes = null;
    try {
      kekBytes = this.generateKek(privateKey);
    } catch (NoSuchAlgorithmException e) {
      Debug.logError(e, module);
    } catch (InvalidKeySpecException e) {
      Debug.logError(e, module);
    } catch (InvalidKeyException e) {
      Debug.logError(e, module);
    }

    // the 3DES KEK value
    SecretKey loadedKek = this.getDesEdeKey(kekBytes);
    byte[] loadKekBytes = loadedKek.getEncoded();

    // test the KEK
    Cipher cipher = this.getCipher(this.getKekKey(), Cipher.ENCRYPT_MODE);
    byte[] kekTestB = {0, 0, 0, 0, 0, 0, 0, 0};
    byte[] kekTestC = new byte[0];
    if (kekTest != null) {
      kekTestB = StringUtil.fromHexString(kekTest);
    }

    // encrypt the test bytes
    try {
      kekTestC = cipher.doFinal(kekTestB);
    } catch (Exception e) {
      Debug.logError(e, module);
    }

    if (!kekOnly) {
      // public key (just Y)
      BigInteger y = publicKey.getY();
      byte[] yBytes = y.toByteArray();
      String yHex = StringUtil.toHexString(yBytes);
      buf.append("======== Begin Public Key (Y @ ")
          .append(yBytes.length)
          .append(" / ")
          .append(yHex.length())
          .append(") ========\n");
      buf.append(yHex).append("\n");
      buf.append("======== End Public Key ========\n\n");

      // private key (just X)
      BigInteger x = privateKey.getX();
      byte[] xBytes = x.toByteArray();
      String xHex = StringUtil.toHexString(xBytes);
      buf.append("======== Begin Private Key (X @ ")
          .append(xBytes.length)
          .append(" / ")
          .append(xHex.length())
          .append(") ========\n");
      buf.append(xHex).append("\n");
      buf.append("======== End Private Key ========\n\n");

      // private key (full)
      byte[] privateBytes = privateKey.getEncoded();
      String privateHex = StringUtil.toHexString(privateBytes);
      buf.append("======== Begin Private Key (Full @ ")
          .append(privateBytes.length)
          .append(" / ")
          .append(privateHex.length())
          .append(") ========\n");
      buf.append(privateHex).append("\n");
      buf.append("======== End Private Key ========\n\n");
    }

    if (kekBytes != null) {
      buf.append("======== Begin KEK (").append(kekBytes.length).append(") ========\n");
      buf.append(StringUtil.toHexString(kekBytes)).append("\n");
      buf.append("======== End KEK ========\n\n");

      buf.append("======== Begin KEK (DES) (").append(loadKekBytes.length).append(") ========\n");
      buf.append(StringUtil.toHexString(loadKekBytes)).append("\n");
      buf.append("======== End KEK (DES) ========\n\n");

      buf.append("======== Begin KEK Test (").append(kekTestC.length).append(") ========\n");
      buf.append(StringUtil.toHexString(kekTestC)).append("\n");
      buf.append("======== End KEK Test ========\n\n");
    } else {
      Debug.logError("KEK came back empty", module);
    }

    return buf;
  }