code: public void sign(PrivateKey key, String algorithm, String provider)
      throws CertificateException, NoSuchAlgorithmException,
          InvalidKeyException, NoSuchProviderException, SignatureException {
          try {
              if (readOnly)
                  throw new CertificateEncodingException(
                                "cannot over-write existing certificate");
              Signature sigEngine = null;
              if ((provider == null) || (provider.length() == 0))
                  sigEngine = Signature.getInstance(algorithm);
              else
                  sigEngine = Signature.getInstance(algorithm, provider);
  
              sigEngine.initSign(key);
  
                                  // in case the name is reset
              algId = AlgorithmId.get(sigEngine.getAlgorithm());
  
              DerOutputStream out = new DerOutputStream();
              DerOutputStream tmp = new DerOutputStream();
  
              // encode certificate info
              info.encode(tmp);
              byte[] rawCert = tmp.toByteArray();
  
              // encode algorithm identifier
              algId.encode(tmp);
  
              // Create and encode the signature itself.
              sigEngine.update(rawCert, 0, rawCert.length);
              signature = sigEngine.sign();
              tmp.putBitString(signature);
  
              // Wrap the signed data in a SEQUENCE { data, algorithm, sig }
              out.write(DerValue.tag_Sequence, tmp);
              signedCert = out.toByteArray();
              readOnly = true;
  
          } catch (IOException e) {
              throw new CertificateEncodingException(e.toString());
        }
      }
docs: Creates an X.509 certificate, and signs it using the given key
  (associating a signature algorithm and an X.500 name).
  This operation is used to implement the certificate generation
  functionality of a certificate authority.
  
  @param key the private key used for signing.
  @param algorithm the name of the signature algorithm used.
  @param provider the name of the provider.
  
  @exception NoSuchAlgorithmException on unsupported signature
  algorithms.
  @exception InvalidKeyException on incorrect key.
  @exception NoSuchProviderException on incorrect provider.
  @exception SignatureException on signature errors.
  @exception CertificateException on encoding errors.