private DERObject createDERForRecipient(byte[] in, X509Certificate cert)
      throws IOException, GeneralSecurityException {

    String s = "1.2.840.113549.3.2";

    AlgorithmParameterGenerator algorithmparametergenerator =
        AlgorithmParameterGenerator.getInstance(s);
    AlgorithmParameters algorithmparameters = algorithmparametergenerator.generateParameters();
    ByteArrayInputStream bytearrayinputstream =
        new ByteArrayInputStream(algorithmparameters.getEncoded("ASN.1"));
    ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream);
    DERObject derobject = asn1inputstream.readObject();
    KeyGenerator keygenerator = KeyGenerator.getInstance(s);
    keygenerator.init(128);
    SecretKey secretkey = keygenerator.generateKey();
    Cipher cipher = Cipher.getInstance(s);
    cipher.init(1, secretkey, algorithmparameters);
    byte[] abyte1 = cipher.doFinal(in);
    DEROctetString deroctetstring = new DEROctetString(abyte1);
    KeyTransRecipientInfo keytransrecipientinfo =
        computeRecipientInfo(cert, secretkey.getEncoded());
    DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo));
    AlgorithmIdentifier algorithmidentifier =
        new AlgorithmIdentifier(new DERObjectIdentifier(s), derobject);
    EncryptedContentInfo encryptedcontentinfo =
        new EncryptedContentInfo(PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring);
    EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, null);
    ContentInfo contentinfo = new ContentInfo(PKCSObjectIdentifiers.envelopedData, env);
    return contentinfo.getDERObject();
  }
  /**
   * @tests javax.crypto.Cipher#getParameters()
   * @tests javax.crypto.Cipher#init(int, java.security.Key, java.security.AlgorithmParameters,
   *     java.security.SecureRandom)
   */
  public void test_getParameters() throws Exception {

    /*
     * If this test is changed, implement the following:
     * test_initILjava_security_KeyLjava_security_AlgorithmParametersLjava_security_SecureRandom()
     */

    SecureRandom sr = new SecureRandom();
    Cipher cipher = null;

    byte[] apEncoding = null;

    byte[] iv = new byte[8];
    sr.nextBytes(iv);

    AlgorithmParameters ap = AlgorithmParameters.getInstance("DESede");
    ap.init(iv, "RAW");
    apEncoding = ap.getEncoded("ASN.1");

    cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap, sr);

    byte[] cipherParmsEnc = cipher.getParameters().getEncoded("ASN.1");
    assertTrue("Parameters differ", Arrays.equals(apEncoding, cipherParmsEnc));
  }
예제 #3
0
  private void testParameters() throws Exception {
    AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("DSA", "BC");
    a.init(512, random);
    AlgorithmParameters params = a.generateParameters();

    byte[] encodeParams = params.getEncoded();

    AlgorithmParameters a2 = AlgorithmParameters.getInstance("DSA", "BC");
    a2.init(encodeParams);

    // a and a2 should be equivalent!
    byte[] encodeParams_2 = a2.getEncoded();

    if (!areEqual(encodeParams, encodeParams_2)) {
      fail("encode/decode parameters failed");
    }

    DSAParameterSpec dsaP = (DSAParameterSpec) params.getParameterSpec(DSAParameterSpec.class);

    KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC");
    g.initialize(dsaP, new SecureRandom());
    KeyPair p = g.generateKeyPair();

    PrivateKey sKey = p.getPrivate();
    PublicKey vKey = p.getPublic();

    Signature s = Signature.getInstance("DSA", "BC");
    byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

    s.initSign(sKey);

    s.update(data);

    byte[] sigBytes = s.sign();

    s = Signature.getInstance("DSA", "BC");

    s.initVerify(vKey);

    s.update(data);

    if (!s.verify(sigBytes)) {
      fail("DSA verification failed");
    }
  }
예제 #4
0
  private void testRandom(int size) throws Exception {
    AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "BC");
    a.init(size, new SecureRandom());
    AlgorithmParameters params = a.generateParameters();

    byte[] encodeParams = params.getEncoded();

    AlgorithmParameters a2 = AlgorithmParameters.getInstance("ElGamal", "BC");
    a2.init(encodeParams);

    // a and a2 should be equivalent!
    byte[] encodeParams_2 = a2.getEncoded();

    if (!areEqual(encodeParams, encodeParams_2)) {
      fail(this.getName() + ": encode/decode parameters failed");
    }

    DHParameterSpec elP = (DHParameterSpec) params.getParameterSpec(DHParameterSpec.class);

    testGP(size, 0, elP.getG(), elP.getP());
  }
예제 #5
0
  private void testGCMGeneric(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C)
      throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
          IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException,
          NoSuchProviderException, IOException, InvalidParameterSpecException {
    Cipher eax = Cipher.getInstance("AES/GCM/NoPadding", "BC");
    SecretKeySpec key = new SecretKeySpec(K, "AES");

    // GCMParameterSpec mapped to AEADParameters and overrides default MAC
    // size
    GCMParameterSpec spec = new GCMParameterSpec(128, N);
    eax.init(Cipher.ENCRYPT_MODE, key, spec);

    eax.updateAAD(A);
    byte[] c = eax.doFinal(P);

    if (!areEqual(C, c)) {
      fail("JCE encrypt with additional data and GCMParameterSpec failed.");
    }

    eax = Cipher.getInstance("GCM", "BC");
    eax.init(Cipher.DECRYPT_MODE, key, spec);
    eax.updateAAD(A);
    byte[] p = eax.doFinal(C);

    if (!areEqual(P, p)) {
      fail("JCE decrypt with additional data and GCMParameterSpec failed.");
    }

    AlgorithmParameters algParams = eax.getParameters();

    byte[] encParams = algParams.getEncoded();

    GCMParameters gcmParameters = GCMParameters.getInstance(encParams);

    if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce())
        || spec.getTLen() != gcmParameters.getIcvLen()) {
      fail("parameters mismatch");
    }

    GCMParameterSpec gcmSpec = algParams.getParameterSpec(GCMParameterSpec.class);

    if (!Arrays.areEqual(gcmSpec.getIV(), gcmParameters.getNonce())
        || gcmSpec.getTLen() != gcmParameters.getIcvLen() * 8) {
      fail("spec parameters mismatch");
    }

    if (!Arrays.areEqual(eax.getIV(), gcmParameters.getNonce())) {
      fail("iv mismatch");
    }
  }
예제 #6
0
 private void encode() throws IOException {
   List algId = new ArrayList(2);
   algId.add(new DERValue(DER.OBJECT_IDENTIFIER, algOid));
   getAlgParameters();
   if (params != null) {
     algId.add(DERReader.read(params.getEncoded()));
   } else {
     algId.add(new DERValue(DER.NULL, null));
   }
   List epki = new ArrayList(2);
   epki.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, algId));
   epki.add(new DERValue(DER.OCTET_STRING, encryptedData));
   encoded = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, epki).getEncoded();
 }
  private static byte[] testParams(AlgorithmParameters rc2Params, RC2ParameterSpec rc2Spec)
      throws Exception {

    // test getParameterSpec returns object equal to input
    rc2Params.init(rc2Spec);
    RC2ParameterSpec rc2OtherSpec =
        (RC2ParameterSpec) rc2Params.getParameterSpec(RC2ParameterSpec.class);
    if (!rc2Spec.equals(rc2OtherSpec)) {
      throw new Exception("AlgorithmParameterSpecs should be equal");
    }

    // test RC2ParameterSpec with RC2 Cipher
    Cipher rc2Cipher = Cipher.getInstance("RC2/CBC/PKCS5PADDING", "SunJCE");
    rc2Cipher.init(
        Cipher.ENCRYPT_MODE, new SecretKeySpec("secret".getBytes("ASCII"), "RC2"), rc2Spec);

    // get IV
    byte[] iv = rc2Cipher.getIV();
    if (!Arrays.equals(iv, rc2Spec.getIV())) {
      throw new Exception("ivs should be equal");
    }

    // test encoding and decoding
    byte[] encoded = rc2Params.getEncoded();
    AlgorithmParameters params = AlgorithmParameters.getInstance("RC2");
    params.init(encoded);

    // test RC2 AlgorithmParameters with RC2 Cipher
    rc2Cipher.init(
        Cipher.ENCRYPT_MODE, new SecretKeySpec("secret".getBytes("ASCII"), "RC2"), params);

    // get IV
    iv = rc2Cipher.getIV();
    if (!Arrays.equals(iv, rc2Spec.getIV())) {
      throw new Exception("ivs should be equal");
    }
    return encoded;
  }
예제 #8
0
  private void testGCMParameterSpecWithRepeatKey(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C)
      throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
          IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException,
          NoSuchProviderException, IOException {
    Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC");
    SecretKeySpec key = new SecretKeySpec(K, "AES");
    GCMParameterSpec spec = new GCMParameterSpec(128, N);
    eax.init(Cipher.ENCRYPT_MODE, key, spec);

    eax.updateAAD(A);
    byte[] c = eax.doFinal(P);

    if (!areEqual(C, c)) {
      fail("JCE encrypt with additional data and RepeatedSecretKeySpec failed.");
    }

    // Check GCMParameterSpec handling knows about RepeatedSecretKeySpec
    eax.init(Cipher.DECRYPT_MODE, new RepeatedSecretKeySpec("AES"), spec);
    eax.updateAAD(A);
    byte[] p = eax.doFinal(C);

    if (!areEqual(P, p)) {
      fail("JCE decrypt with additional data and RepeatedSecretKeySpec failed.");
    }

    AlgorithmParameters algParams = eax.getParameters();

    byte[] encParams = algParams.getEncoded();

    GCMParameters gcmParameters = GCMParameters.getInstance(encParams);

    if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce())
        || spec.getTLen() != gcmParameters.getIcvLen()) {
      fail("parameters mismatch");
    }
  }
  /**
   * Constructs an <code>EncryptedPrivateKeyInfo</code> from the encryption algorithm parameters and
   * the encrypted data.
   *
   * <p>Note: the <code>encrypedData</code> is cloned when constructing this object.
   *
   * @param algParams the algorithm parameters for the encryption algorithm. <code>
   *     algParams.getEncoded()</code> should return the ASN.1 encoded bytes of the <code>parameters
   *     </code> field of the <code>AlgorithmIdentifer</code> component of the <code>
   *     EncryptedPrivateKeyInfo</code> type.
   * @param encryptedData encrypted data.
   * @exception NullPointerException if <code>algParams</code> or <code>encryptedData</code> is
   *     null.
   * @exception IllegalArgumentException if <code>encryptedData</code> is empty, i.e. 0-length.
   * @exception NoSuchAlgorithmException if the specified algName of the specified <code>algParams
   *     </code> parameter is not supported.
   */
  public EncryptedPrivateKeyInfo(AlgorithmParameters algParams, byte[] encryptedData)
      throws NullPointerException, IllegalArgumentException, NoSuchAlgorithmException {
    if (algParams == null || encryptedData == null) {
      throw new NullPointerException("parameters null");
    }

    org.bouncycastle.asn1.x509.AlgorithmIdentifier kAlgId = null;

    try {
      ByteArrayInputStream bIn = new ByteArrayInputStream(algParams.getEncoded());
      ASN1InputStream dIn = new ASN1InputStream(bIn);

      kAlgId =
          new AlgorithmIdentifier(
              new DERObjectIdentifier(algParams.getAlgorithm()), dIn.readObject());
    } catch (IOException e) {
      throw new IllegalArgumentException("error in encoding: " + e.toString());
    }

    infoObj =
        new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(
            kAlgId, (byte[]) encryptedData.clone());
    algP = this.getParameters();
  }
  /**
   * Parse a DER stream into an X.509 certificate.
   *
   * @param encoded The encoded bytes.
   */
  private void parse(InputStream encoded) throws Exception {
    DERReader der = new DERReader(encoded);

    // Certificate ::= SEQUENCE {
    DERValue cert = der.read();
    debug("start Certificate  len == " + cert.getLength());

    this.encoded = cert.getEncoded();
    if (!cert.isConstructed()) {
      throw new IOException("malformed Certificate");
    }

    // TBSCertificate ::= SEQUENCE {
    DERValue tbsCert = der.read();
    if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE) {
      throw new IOException("malformed TBSCertificate");
    }
    tbsCertBytes = tbsCert.getEncoded();
    debug("start TBSCertificate  len == " + tbsCert.getLength());

    // Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }
    DERValue val = der.read();
    if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0) {
      version = ((BigInteger) der.read().getValue()).intValue() + 1;
      val = der.read();
    } else {
      version = 1;
    }
    debug("read version == " + version);

    // SerialNumber ::= INTEGER
    serialNo = (BigInteger) val.getValue();
    debug("read serial number == " + serialNo);

    // AlgorithmIdentifier ::= SEQUENCE {
    val = der.read();
    if (!val.isConstructed()) {
      throw new IOException("malformed AlgorithmIdentifier");
    }
    int certAlgLen = val.getLength();
    debug("start AlgorithmIdentifier  len == " + certAlgLen);
    val = der.read();

    //   algorithm    OBJECT IDENTIFIER,
    algId = (OID) val.getValue();
    debug("read algorithm ID == " + algId);

    //   parameters   ANY DEFINED BY algorithm OPTIONAL }
    if (certAlgLen > val.getEncodedLength()) {
      val = der.read();
      if (val == null) {
        algVal = null;
      } else {
        algVal = val.getEncoded();
      }
      if (val.isConstructed()) {
        encoded.skip(val.getLength());
      }
      debug("read algorithm parameters == " + algVal);
    }

    // issuer   Name,
    val = der.read();
    issuer = new X500Name(val.getEncoded());
    der.skip(val.getLength());
    debug("read issuer == " + issuer);

    // Validity ::= SEQUENCE {
    //   notBefore   Time,
    //   notAfter    Time }
    if (!der.read().isConstructed()) {
      throw new IOException("malformed Validity");
    }
    notBefore = (Date) der.read().getValue();
    notAfter = (Date) der.read().getValue();
    debug("read notBefore == " + notBefore);
    debug("read notAfter == " + notAfter);

    // subject   Name,
    val = der.read();
    subject = new X500Name(val.getEncoded());
    der.skip(val.getLength());
    debug("read subject == " + subject);

    // SubjectPublicKeyInfo ::= SEQUENCE {
    //   algorithm         AlgorithmIdentifier,
    //   subjectPublicKey  BIT STRING }
    DERValue spki = der.read();
    if (!spki.isConstructed()) {
      throw new IOException("malformed SubjectPublicKeyInfo");
    }
    KeyFactory spkFac = KeyFactory.getInstance("X.509");
    subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
    der.skip(spki.getLength());
    debug("read subjectPublicKey == " + subjectKey);

    if (version > 1) {
      val = der.read();
    }
    if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1) {
      byte[] b = (byte[]) val.getValue();
      issuerUniqueId = new BitString(b, 1, b.length - 1, b[0] & 0xFF);
      debug("read issuerUniqueId == " + issuerUniqueId);
      val = der.read();
    }
    if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2) {
      byte[] b = (byte[]) val.getValue();
      subjectUniqueId = new BitString(b, 1, b.length - 1, b[0] & 0xFF);
      debug("read subjectUniqueId == " + subjectUniqueId);
      val = der.read();
    }
    if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3) {
      val = der.read();
      debug("start Extensions  len == " + val.getLength());
      int len = 0;
      while (len < val.getLength()) {
        DERValue ext = der.read();
        debug("start extension  len == " + ext.getLength());
        Extension e = new Extension(ext.getEncoded());
        extensions.put(e.getOid(), e);
        der.skip(ext.getLength());
        len += ext.getEncodedLength();
        debug("count == " + len);
      }
    }

    val = der.read();
    if (!val.isConstructed()) {
      throw new IOException("malformed AlgorithmIdentifier");
    }
    int sigAlgLen = val.getLength();
    debug("start AlgorithmIdentifier  len == " + sigAlgLen);
    val = der.read();
    sigAlgId = (OID) val.getValue();
    debug("read algorithm id == " + sigAlgId);
    if (sigAlgLen > val.getEncodedLength()) {
      val = der.read();
      if (val.getValue() == null) {
        if (subjectKey instanceof DSAPublicKey) {
          AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
          DSAParams dsap = ((DSAPublicKey) subjectKey).getParams();
          DSAParameterSpec spec = new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG());
          params.init(spec);
          sigAlgVal = params.getEncoded();
        }
      } else {
        sigAlgVal = (byte[]) val.getEncoded();
      }
      if (val.isConstructed()) {
        encoded.skip(val.getLength());
      }
      debug("read parameters == " + sigAlgVal);
    }
    signature = ((BitString) der.read().getValue()).toByteArray();
    debug("read signature ==\n" + Util.hexDump(signature, ">>>> "));
  }
  public OutputEncryptor build() throws OperatorCreationException {
    final AlgorithmIdentifier algID;

    salt = new byte[20];

    if (random == null) {
      random = new SecureRandom();
    }

    random.nextBytes(salt);

    try {
      this.cipher = helper.createCipher(algOID.getId());

      if (PEMUtilities.isPKCS5Scheme2(algOID)) {
        this.paramGen = helper.createAlgorithmParameterGenerator(algOID.getId());
      } else {
        this.secKeyFact = helper.createSecretKeyFactory(algOID.getId());
      }
    } catch (GeneralSecurityException e) {
      throw new OperatorCreationException(algOID + " not available: " + e.getMessage(), e);
    }

    if (PEMUtilities.isPKCS5Scheme2(algOID)) {
      params = paramGen.generateParameters();

      try {
        KeyDerivationFunc scheme =
            new KeyDerivationFunc(algOID, ASN1Primitive.fromByteArray(params.getEncoded()));
        KeyDerivationFunc func =
            new KeyDerivationFunc(
                PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount));

        ASN1EncodableVector v = new ASN1EncodableVector();

        v.add(func);
        v.add(scheme);

        algID =
            new AlgorithmIdentifier(
                PKCSObjectIdentifiers.id_PBES2, PBES2Parameters.getInstance(new DERSequence(v)));
      } catch (IOException e) {
        throw new OperatorCreationException(e.getMessage(), e);
      }

      key =
          PEMUtilities.generateSecretKeyForPKCS5Scheme2(
              algOID.getId(), password, salt, iterationCount);

      try {
        cipher.init(Cipher.ENCRYPT_MODE, key, params);
      } catch (GeneralSecurityException e) {
        throw new OperatorCreationException(e.getMessage(), e);
      }
    } else if (PEMUtilities.isPKCS12(algOID)) {
      ASN1EncodableVector v = new ASN1EncodableVector();

      v.add(new DEROctetString(salt));
      v.add(new ASN1Integer(iterationCount));

      algID = new AlgorithmIdentifier(algOID, PKCS12PBEParams.getInstance(new DERSequence(v)));

      try {
        PBEKeySpec pbeSpec = new PBEKeySpec(password);
        PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount);

        key = secKeyFact.generateSecret(pbeSpec);

        cipher.init(Cipher.ENCRYPT_MODE, key, defParams);
      } catch (GeneralSecurityException e) {
        throw new OperatorCreationException(e.getMessage(), e);
      }
    } else {
      throw new OperatorCreationException("unknown algorithm: " + algOID, null);
    }

    return new OutputEncryptor() {
      public AlgorithmIdentifier getAlgorithmIdentifier() {
        return algID;
      }

      public OutputStream getOutputStream(OutputStream encOut) {
        return new CipherOutputStream(encOut, cipher);
      }

      public GenericKey getKey() {
        return new JceGenericKey(algID, key);
      }
    };
  }
예제 #12
0
  public void performTest() throws Exception {
    KeyFactory fact;
    byte[] input =
        new byte[] {
          (byte) 0x54,
          (byte) 0x85,
          (byte) 0x9b,
          (byte) 0x34,
          (byte) 0x2c,
          (byte) 0x49,
          (byte) 0xea,
          (byte) 0x2a
        };
    byte[][] output =
        new byte[][] {
          Hex.decode(
              "8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"),
          Hex.decode(
              "2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"),
          Hex.decode(
              "0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"),
          Hex.decode(
              "1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"),
          Hex.decode(
              "4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"),
          Hex.decode(
              "06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"),
          Hex.decode(
              "135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"),
          Hex.decode(
              "03c05add1e030178c352face07cafc9447c8f369b8f95125c0d311c16b6da48ca2067104cce6cd21ae7b163cd18ffc13001aecebdc2eb02b9e92681f84033a98"),
          Hex.decode(
              "00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c")
        };
    SecureRandom rand = new FixedSecureRandom();

    fact = KeyFactory.getInstance("RSA", "BC");

    PrivateKey privKey = fact.generatePrivate(privKeySpec);
    PublicKey pubKey = fact.generatePublic(pubKeySpec);

    PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec);
    PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec);

    //
    // key without CRT coefficients
    //
    PrivateKeyInfo keyInfo = PrivateKeyInfo.getInstance(privKey.getEncoded());
    BigInteger zero = BigInteger.valueOf(0);
    PKCS8EncodedKeySpec noCrtSpec =
        new PKCS8EncodedKeySpec(
            new PrivateKeyInfo(
                    keyInfo.getPrivateKeyAlgorithm(),
                    new org.mightyfish.asn1.pkcs.RSAPrivateKey(
                        privKeySpec.getModulus(),
                        privKeySpec.getPublicExponent(),
                        privKeySpec.getPrivateExponent(),
                        zero,
                        zero,
                        zero,
                        zero,
                        zero))
                .getEncoded());

    PrivateKey noCrtKey = fact.generatePrivate(noCrtSpec);
    if (noCrtKey instanceof RSAPrivateCrtKey) {
      fail("private key without CRT coefficients returned as CRT key");
    }

    //
    // No Padding
    //
    Cipher c = Cipher.getInstance("RSA", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    byte[] out = c.doFinal(input);

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // No Padding - incremental
    //
    c = Cipher.getInstance("RSA", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    c.update(input);

    out = c.doFinal();

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // No Padding - incremental - explicit use of NONE in mode.
    //
    c = Cipher.getInstance("RSA/NONE/NoPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    c.update(input);

    out = c.doFinal();

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // No Padding - maximum length
    //
    c = Cipher.getInstance("RSA", "BC");

    byte[] modBytes = ((RSAPublicKey) pubKey).getModulus().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(maxInput);

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // PKCS1 V 1.5
    //
    c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[1])) {
      fail(
          "PKCS1 test failed on encrypt expected "
              + new String(Hex.encode(output[1]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // PKCS1 V 1.5 - NONE
    //
    c = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[1])) {
      fail(
          "PKCS1 test failed on encrypt expected "
              + new String(Hex.encode(output[1]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // OAEP - SHA1
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[2])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    AlgorithmParameters oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-1 parameters");
    }

    //
    // OAEP - SHA224
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA224AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[3])) {
      fail(
          "OAEP SHA-224 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-224 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-224 parameters");
    }

    //
    // OAEP - SHA 256
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[4])) {
      fail(
          "OAEP SHA-256 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-256 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-256 parameters");
    }

    //
    // OAEP - SHA 384
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA384AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[5])) {
      fail(
          "OAEP SHA-384 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-384 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-384 parameters");
    }

    //
    // OAEP - MD5
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithMD5AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[6])) {
      fail(
          "OAEP MD5 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default md5 parameters");
    }

    //
    // OAEP - SHA1 with default parameters
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, OAEPParameterSpec.DEFAULT, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[2])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    oaepP = c.getParameters();

    if (!areEqual(oaepP.getEncoded(), new byte[] {0x30, 0x00})) {
      fail("OAEP test failed default parameters");
    }

    //
    // OAEP - SHA1 with specified string
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(
        Cipher.ENCRYPT_MODE,
        pubKey,
        new OAEPParameterSpec(
            "SHA1",
            "MGF1",
            new MGF1ParameterSpec("SHA1"),
            new PSource.PSpecified(new byte[] {1, 2, 3, 4, 5})),
        rand);

    out = c.doFinal(input);

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified,
                    new DEROctetString(new byte[] {1, 2, 3, 4, 5})))
            .getEncoded())) {
      fail("OAEP test failed changed sha-1 parameters");
    }

    if (!areEqual(out, output[7])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey, oaepP);

    out = c.doFinal(out);

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

    //
    // ISO9796-1
    //
    byte[] isoInput =
        Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210");
    PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec);
    PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec);

    c = Cipher.getInstance("RSA/NONE/ISO9796-1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, isoPrivKey);

    out = c.doFinal(isoInput);

    if (!areEqual(out, output[8])) {
      fail(
          "ISO9796-1 test failed on encrypt expected "
              + new String(Hex.encode(output[3]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, isoPubKey);

    out = c.doFinal(out);

    if (!areEqual(out, isoInput)) {
      fail(
          "ISO9796-1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    //
    // generation with parameters test.
    //
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");

    //
    // 768 bit RSA with e = 2^16-1
    //
    keyPairGen.initialize(
        new RSAKeyGenParameterSpec(768, BigInteger.valueOf(65537)), new SecureRandom());

    KeyPair kp = keyPairGen.generateKeyPair();

    pubKey = kp.getPublic();
    privKey = kp.getPrivate();

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

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

    //
    // comparison check
    //
    KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC");

    RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) keyFact.translateKey(privKey);

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    crtKey =
        (RSAPrivateCrtKey) keyFact.generatePrivate(new PKCS8EncodedKeySpec(privKey.getEncoded()));

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    crtKey = (RSAPrivateCrtKey) serializeDeserialize(privKey);

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    if (privKey.hashCode() != crtKey.hashCode()) {
      fail("private key hashCode check failed");
    }

    RSAPublicKey copyKey = (RSAPublicKey) keyFact.translateKey(pubKey);

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    copyKey = (RSAPublicKey) keyFact.generatePublic(new X509EncodedKeySpec(pubKey.getEncoded()));

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    copyKey = (RSAPublicKey) serializeDeserialize(pubKey);

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    if (pubKey.hashCode() != copyKey.hashCode()) {
      fail("public key hashCode check failed");
    }

    //
    // test an OAEP key
    //
    SubjectPublicKeyInfo oaepKey =
        new SubjectPublicKeyInfo(
            new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, new RSAESOAEPparams()),
            SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()).parsePublicKey());

    copyKey =
        (RSAPublicKey)
            serializeDeserialize(
                keyFact.generatePublic(new X509EncodedKeySpec(oaepKey.getEncoded())));

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    if (pubKey.hashCode() != copyKey.hashCode()) {
      fail("public key hashCode check failed");
    }

    if (!Arrays.areEqual(copyKey.getEncoded(), oaepKey.getEncoded())) {
      fail("encoding does not match");
    }

    oaepCompatibilityTest("SHA-1", priv2048Key, pub2048Key);
    // TODO: oaepCompatibilityTest("SHA-224", priv2048Key, pub2048Key);      commented out as fails
    // in JDK 1.7
    oaepCompatibilityTest("SHA-256", priv2048Key, pub2048Key);
    oaepCompatibilityTest("SHA-384", priv2048Key, pub2048Key);
    oaepCompatibilityTest("SHA-512", priv2048Key, pub2048Key);

    SecureRandom random = new SecureRandom();
    rawModeTest("SHA1withRSA", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random);
    rawModeTest("MD5withRSA", PKCSObjectIdentifiers.md5, priv2048Key, pub2048Key, random);
    rawModeTest(
        "RIPEMD128withRSA", TeleTrusTObjectIdentifiers.ripemd128, priv2048Key, pub2048Key, random);

    // init reset test
    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.update(new byte[40]);

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.update(new byte[40]);
  }
예제 #13
0
  public void performTest() throws Exception {
    KeyFactory fact = KeyFactory.getInstance("RSA", "SC");

    PrivateKey privKey = fact.generatePrivate(privKeySpec);
    PublicKey pubKey = fact.generatePublic(pubKeySpec);

    Signature s = Signature.getInstance("SHA1withRSA/PSS", "SC");

    s.initSign(privKey, new FixedRandom(slt1a));
    s.update(msg1a);
    byte[] sig = s.sign();

    if (!arrayEquals(sig1a, sig)) {
      fail(
          "PSS Sign test expected "
              + new String(Hex.encode(sig1a))
              + " got "
              + new String(Hex.encode(sig)));
    }

    s = Signature.getInstance("SHA1withRSAandMGF1", "SC");

    s.initVerify(pubKey);
    s.update(msg1a);
    if (!s.verify(sig1a)) {
      fail("SHA1 signature verification failed");
    }

    s = Signature.getInstance("SHA1withRSAandMGF1", "SC");

    s.setParameter(PSSParameterSpec.DEFAULT);

    s.initVerify(pubKey);
    s.update(msg1a);
    if (!s.verify(sig1a)) {
      fail("SHA1 signature verification with default parameters failed");
    }

    AlgorithmParameters pss = s.getParameters();
    if (!arrayEquals(pss.getEncoded(), new byte[] {0x30, 0x00})) {
      fail("failed default encoding test.");
    }

    s = Signature.getInstance("SHA256withRSA/PSS", "SC");

    s.initSign(privKey, new FixedRandom(slt1a));
    s.update(msg1a);
    sig = s.sign();

    pss = s.getParameters();

    if (!arrayEquals(sig1b, sig)) {
      fail(
          "PSS Sign test expected "
              + new String(Hex.encode(sig1b))
              + " got "
              + new String(Hex.encode(sig)));
    }

    s = Signature.getInstance("SHA256withRSAandMGF1", "SC");

    s.setParameter(pss.getParameterSpec(PSSParameterSpec.class));

    s.initVerify(pubKey);
    s.update(msg1a);
    if (!s.verify(sig1b)) {
      fail("SHA256 signature verification failed");
    }

    //
    // 512 test -with zero salt length
    //
    s = Signature.getInstance("SHA512withRSAandMGF1", "SC");

    s.setParameter(new PSSParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), 0, 1));
    s.initSign(privKey);

    s.update(msg1a);
    sig = s.sign();

    pss = s.getParameters();

    if (!arrayEquals(sig1c, sig)) {
      fail(
          "PSS Sign test expected "
              + new String(Hex.encode(sig1c))
              + " got "
              + new String(Hex.encode(sig)));
    }

    s = Signature.getInstance("SHA512withRSAandMGF1", "SC");

    s.setParameter(pss.getParameterSpec(PSSParameterSpec.class));

    s.initVerify(pubKey);
    s.update(msg1a);
    if (!s.verify(sig1c)) {
      fail("SHA512 signature verification failed");
    }

    SecureRandom random = new SecureRandom();

    // Note: PSS minimum key size determined by hash/salt lengths
    PrivateKey priv2048Key = fact.generatePrivate(RSATest.priv2048KeySpec);
    PublicKey pub2048Key = fact.generatePublic(RSATest.pub2048KeySpec);

    rawModeTest("SHA1withRSA/PSS", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random);
    rawModeTest(
        "SHA224withRSA/PSS", NISTObjectIdentifiers.id_sha224, priv2048Key, pub2048Key, random);
    rawModeTest(
        "SHA256withRSA/PSS", NISTObjectIdentifiers.id_sha256, priv2048Key, pub2048Key, random);
    rawModeTest(
        "SHA384withRSA/PSS", NISTObjectIdentifiers.id_sha384, priv2048Key, pub2048Key, random);
    rawModeTest(
        "SHA512withRSA/PSS", NISTObjectIdentifiers.id_sha512, priv2048Key, pub2048Key, random);
  }