예제 #1
0
  public static void writeDSAPrivateKey(
      Writer _out, DSAPrivateKey obj, CipherSpec cipher, char[] passwd) throws IOException {
    BufferedWriter out = makeBuffered(_out);
    PrivateKeyInfo info =
        new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(getEncoded(obj)).readObject());
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ASN1OutputStream aOut = new ASN1OutputStream(bOut);

    DSAParameter p = DSAParameter.getInstance(info.getAlgorithmId().getParameters());
    ASN1EncodableVector v = new ASN1EncodableVector();
    v.add(new DERInteger(0));
    v.add(new DERInteger(p.getP()));
    v.add(new DERInteger(p.getQ()));
    v.add(new DERInteger(p.getG()));

    BigInteger x = obj.getX();
    BigInteger y = p.getG().modPow(x, p.getP());

    v.add(new DERInteger(y));
    v.add(new DERInteger(x));

    aOut.writeObject(new DERSequence(v));
    byte[] encoding = bOut.toByteArray();

    if (cipher != null && passwd != null) {
      writePemEncrypted(out, PEM_STRING_DSA, encoding, cipher, passwd);
    } else {
      writePemPlain(out, PEM_STRING_DSA, encoding);
    }
  }
  /**
   * Converts, if possible, a key specification into a {@link BCMcElieceCCA2PrivateKey}. Currently,
   * the following key specifications are supported: {@link McElieceCCA2PrivateKeySpec}, {@link
   * PKCS8EncodedKeySpec}.
   *
   * @param keySpec the key specification
   * @return the McEliece CCA2 private key
   * @throws InvalidKeySpecException if the KeySpec is not supported.
   */
  public PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException {
    if (keySpec instanceof McElieceCCA2PrivateKeySpec) {
      return new BCMcElieceCCA2PrivateKey((McElieceCCA2PrivateKeySpec) keySpec);
    } else if (keySpec instanceof PKCS8EncodedKeySpec) {
      // get the DER-encoded Key according to PKCS#8 from the spec
      byte[] encKey = ((PKCS8EncodedKeySpec) keySpec).getEncoded();

      // decode the PKCS#8 data structure to the pki object
      PrivateKeyInfo pki;

      try {
        pki = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey));
      } catch (IOException e) {
        throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec: " + e);
      }

      try {
        // get the inner type inside the BIT STRING
        ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive();

        // build and return the actual key
        ASN1Sequence privKey = (ASN1Sequence) innerType;

        // decode oidString (but we don't need it right now)
        String oidString = ((ASN1ObjectIdentifier) privKey.getObjectAt(0)).toString();

        // decode <n>
        BigInteger bigN = ((ASN1Integer) privKey.getObjectAt(1)).getValue();
        int n = bigN.intValue();

        // decode <k>
        BigInteger bigK = ((ASN1Integer) privKey.getObjectAt(2)).getValue();
        int k = bigK.intValue();

        // decode <fieldPoly>
        byte[] encFieldPoly = ((ASN1OctetString) privKey.getObjectAt(3)).getOctets();
        // decode <goppaPoly>
        byte[] encGoppaPoly = ((ASN1OctetString) privKey.getObjectAt(4)).getOctets();
        // decode <p>
        byte[] encP = ((ASN1OctetString) privKey.getObjectAt(5)).getOctets();
        // decode <h>
        byte[] encH = ((ASN1OctetString) privKey.getObjectAt(6)).getOctets();
        // decode <qInv>
        ASN1Sequence qSeq = (ASN1Sequence) privKey.getObjectAt(7);
        byte[][] encQInv = new byte[qSeq.size()][];
        for (int i = 0; i < qSeq.size(); i++) {
          encQInv[i] = ((ASN1OctetString) qSeq.getObjectAt(i)).getOctets();
        }

        return new BCMcElieceCCA2PrivateKey(
            new McElieceCCA2PrivateKeySpec(
                OID, n, k, encFieldPoly, encGoppaPoly, encP, encH, encQInv));

      } catch (IOException cce) {
        throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec.");
      }
    }

    throw new InvalidKeySpecException("Unsupported key specification: " + keySpec.getClass() + ".");
  }
예제 #3
0
 /** c: PEM_read_PrivateKey + PEM_read_bio_PrivateKey CAUTION: KeyPair#getPublic() may be null. */
 public static KeyPair readPrivateKey(Reader in, char[] password) throws IOException {
   BufferedReader _in = makeBuffered(in);
   String line;
   while ((line = _in.readLine()) != null) {
     if (line.indexOf(BEF_G + PEM_STRING_RSA) != -1) {
       try {
         return readKeyPair(_in, password, "RSA", BEF_E + PEM_STRING_RSA);
       } catch (Exception e) {
         throw new IOException("problem creating RSA private key: " + e.toString());
       }
     } else if (line.indexOf(BEF_G + PEM_STRING_DSA) != -1) {
       try {
         return readKeyPair(_in, password, "DSA", BEF_E + PEM_STRING_DSA);
       } catch (Exception e) {
         throw new IOException("problem creating DSA private key: " + e.toString());
       }
     } else if (line.indexOf(BEF_G + PEM_STRING_ECPRIVATEKEY) != -1) {
       throw new IOException("EC private key not supported");
     } else if (line.indexOf(BEF_G + PEM_STRING_PKCS8INF) != -1) {
       try {
         byte[] bytes = readBytes(_in, BEF_E + PEM_STRING_PKCS8INF);
         PrivateKeyInfo info =
             new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(bytes).readObject());
         String type = getPrivateKeyTypeFromObjectId(info.getAlgorithmId().getObjectId());
         return org.jruby.ext.openssl.impl.PKey.readPrivateKey(
             info.getPrivateKey().getDEREncoded(), type);
       } catch (Exception e) {
         throw new IOException("problem creating private key: " + e.toString());
       }
     } else if (line.indexOf(BEF_G + PEM_STRING_PKCS8) != -1) {
       try {
         byte[] bytes = readBytes(_in, BEF_E + PEM_STRING_PKCS8);
         org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn =
             new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(
                 (ASN1Sequence) new ASN1InputStream(bytes).readObject());
         AlgorithmIdentifier algId = eIn.getEncryptionAlgorithm();
         PrivateKey privKey;
         if (algId.getAlgorithm().toString().equals("1.2.840.113549.1.5.13")) { // PBES2
           privKey = derivePrivateKeyPBES2(eIn, algId, password);
         } else {
           privKey = derivePrivateKeyPBES1(eIn, algId, password);
         }
         return new KeyPair(null, privKey);
       } catch (Exception e) {
         throw new IOException("problem creating private key: " + e.toString());
       }
     }
   }
   return null;
 }
예제 #4
0
  /** create a private key from the given public key info object. */
  static PrivateKey createPrivateKeyFromPrivateKeyInfo(PrivateKeyInfo info) {
    DERObjectIdentifier algOid = info.getAlgorithmId().getObjectId();

    if (RSAUtil.isRsaOid(algOid)) {
      return new JCERSAPrivateCrtKey(info);
    } else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) {
      return new JCEDHPrivateKey(info);
    }
    // BEGIN android-removed
    // else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm))
    // {
    //       return new JCEElGamalPrivateKey(info);
    // }
    // END android-removed
    else if (algOid.equals(X9ObjectIdentifiers.id_dsa)) {
      return new JDKDSAPrivateKey(info);
    }
    // BEGIN android-removed
    // else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
    // {
    //       return new JCEECPrivateKey(info);
    // }
    // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94))
    // {
    //       return new JDKGOST3410PrivateKey(info);
    // }
    // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001))
    // {
    //       return new JCEECPrivateKey(info);
    // }
    // END android-removed
    else {
      throw new RuntimeException("algorithm identifier " + algOid + " in key not recognised");
    }
  }
 public PrivateKey generatePrivate(PrivateKeyInfo pki) throws InvalidKeySpecException {
   // get the inner type inside the BIT STRING
   try {
     ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive();
     McElieceCCA2PrivateKey key = McElieceCCA2PrivateKey.getInstance(innerType);
     return new BCMcElieceCCA2PrivateKey(
         key.getOID().getId(),
         key.getN(),
         key.getK(),
         key.getField(),
         key.getGoppaPoly(),
         key.getP(),
         key.getH(),
         key.getQInv());
   } catch (IOException cce) {
     throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec");
   }
 }
예제 #6
0
  private PemObject createPemObject(Object o) throws IOException {
    String type;
    byte[] encoding;

    if (o instanceof PemObject) {
      return (PemObject) o;
    }
    if (o instanceof PemObjectGenerator) {
      return ((PemObjectGenerator) o).generate();
    }
    if (o instanceof X509Certificate) {
      type = "CERTIFICATE";
      try {
        encoding = ((X509Certificate) o).getEncoded();
      } catch (CertificateEncodingException e) {
        throw new PemGenerationException("Cannot encode object: " + e.toString());
      }
    } else if (o instanceof X509CRL) {
      type = "X509 CRL";
      try {
        encoding = ((X509CRL) o).getEncoded();
      } catch (CRLException e) {
        throw new PemGenerationException("Cannot encode object: " + e.toString());
      }
    } else if (o instanceof KeyPair) {
      return createPemObject(((KeyPair) o).getPrivate());
    } else if (o instanceof PrivateKey) {
      PrivateKeyInfo info =
          new PrivateKeyInfo((ASN1Sequence) ASN1Primitive.fromByteArray(((Key) o).getEncoded()));

      if (o instanceof RSAPrivateKey) {
        type = "RSA PRIVATE KEY";

        encoding = info.parsePrivateKey().toASN1Primitive().getEncoded();
      } else if (o instanceof DSAPrivateKey) {
        type = "DSA PRIVATE KEY";

        DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters());
        ASN1EncodableVector v = new ASN1EncodableVector();

        v.add(new DERInteger(0));
        v.add(new DERInteger(p.getP()));
        v.add(new DERInteger(p.getQ()));
        v.add(new DERInteger(p.getG()));

        BigInteger x = ((DSAPrivateKey) o).getX();
        BigInteger y = p.getG().modPow(x, p.getP());

        v.add(new DERInteger(y));
        v.add(new DERInteger(x));

        encoding = new DERSequence(v).getEncoded();
      } else if (((PrivateKey) o).getAlgorithm().equals("ECDSA")) {
        type = "EC PRIVATE KEY";

        encoding = info.parsePrivateKey().toASN1Primitive().getEncoded();
      } else {
        throw new IOException("Cannot identify private key");
      }
    } else if (o instanceof PublicKey) {
      type = "PUBLIC KEY";

      encoding = ((PublicKey) o).getEncoded();
    } else if (o instanceof X509AttributeCertificate) {
      type = "ATTRIBUTE CERTIFICATE";
      encoding = ((X509V2AttributeCertificate) o).getEncoded();
    } else if (o instanceof PKCS10CertificationRequest) {
      type = "CERTIFICATE REQUEST";
      encoding = ((PKCS10CertificationRequest) o).getEncoded();
    } else if (o instanceof ContentInfo) {
      type = "PKCS7";
      encoding = ((ContentInfo) o).getEncoded();
    } else {
      throw new PemGenerationException("unknown object passed - can't encode.");
    }

    return new PemObject(type, encoding);
  }
예제 #7
0
  private PemObject createPemObject(
      Object obj, String algorithm, char[] password, SecureRandom random) throws IOException {
    if (obj instanceof KeyPair) {
      return createPemObject(((KeyPair) obj).getPrivate(), algorithm, password, random);
    }

    String type = null;
    byte[] keyData = null;

    if (obj instanceof RSAPrivateCrtKey) {
      type = "RSA PRIVATE KEY";

      RSAPrivateCrtKey k = (RSAPrivateCrtKey) obj;

      org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct =
          new org.bouncycastle.asn1.pkcs.RSAPrivateKey(
              k.getModulus(),
              k.getPublicExponent(),
              k.getPrivateExponent(),
              k.getPrimeP(),
              k.getPrimeQ(),
              k.getPrimeExponentP(),
              k.getPrimeExponentQ(),
              k.getCrtCoefficient());

      // convert to bytearray
      keyData = keyStruct.getEncoded();
    } else if (obj instanceof DSAPrivateKey) {
      type = "DSA PRIVATE KEY";

      DSAPrivateKey k = (DSAPrivateKey) obj;
      DSAParams p = k.getParams();
      ASN1EncodableVector v = new ASN1EncodableVector();

      v.add(new DERInteger(0));
      v.add(new DERInteger(p.getP()));
      v.add(new DERInteger(p.getQ()));
      v.add(new DERInteger(p.getG()));

      BigInteger x = k.getX();
      BigInteger y = p.getG().modPow(x, p.getP());

      v.add(new DERInteger(y));
      v.add(new DERInteger(x));

      keyData = new DERSequence(v).getEncoded();
    } else if (obj instanceof PrivateKey && "ECDSA".equals(((PrivateKey) obj).getAlgorithm())) {
      type = "EC PRIVATE KEY";

      PrivateKeyInfo privInfo =
          PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(((PrivateKey) obj).getEncoded()));

      keyData = privInfo.parsePrivateKey().toASN1Primitive().getEncoded();
    }

    if (type == null || keyData == null) {
      // TODO Support other types?
      throw new IllegalArgumentException("Object type not supported: " + obj.getClass().getName());
    }

    String dekAlgName = Strings.toUpperCase(algorithm);

    // Note: For backward compatibility
    if (dekAlgName.equals("DESEDE")) {
      dekAlgName = "DES-EDE3-CBC";
    }

    int ivLength = dekAlgName.startsWith("AES-") ? 16 : 8;

    byte[] iv = new byte[ivLength];
    random.nextBytes(iv);

    byte[] encData = PEMUtilities.crypt(true, provider, keyData, password, dekAlgName, iv);

    List headers = new ArrayList(2);

    headers.add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
    headers.add(new PemHeader("DEK-Info", dekAlgName + "," + getHexEncoded(iv)));

    return new PemObject(type, headers, encData);
  }