15

私のタスクは次のとおりです。

  • 作成したキーストアから公開鍵と秘密鍵を取得します。
  • これらのキーを使用して、私の RSA 2048 ビット公開キーを使用して段落を暗号化します。
  • DSA-SHA-1 署名アルゴリズムを使用して結果にデジタル署名します。
  • デジタル署名の出力を というファイルに保存しますoutput.dat

以下のプログラムはエラーをスローしています: "java.security.InvalidKeyException: インストールされたプロバイダはこのキーをサポートしていません: sun.security.provider.DSAPublicKeyImpl".

import java.security.*;
import java.security.KeyStore.*;
import java.io.*;
import java.security.PublicKey;
import java.security.PrivateKey;
import javax.crypto.Cipher;
import java.nio.charset.*;
import sun.security.provider.*;
import  javax.crypto.*;

public class Code {

/**
 * @param args the command line arguments
 */
    public static void main(String[] args) {

        try {

            /* getting data for keystore */

            File file = new File(System.getProperty("user.home") + File.separatorChar + ".keystore");
            FileInputStream is = new FileInputStream(file);
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());

            /*Information for certificate to be generated */ 
            String password = "abcde";
            String alias = "mykeys";
            String alias1 = "skeys";

            String filepath ="C:\\email.txt";

            /* getting the key*/
            keystore.load(is, password.toCharArray());
            PrivateKey key = (PrivateKey)keystore.getKey(alias, "bemylife".toCharArray());
            //PrivateKey key = cert1.getPrivateKey();
            //PublicKey key1= (PrivateKey)key;

            /* Get certificate of public key */
            java.security.cert.Certificate cert = keystore.getCertificate(alias); 

            /* Here it prints the public key*/
            System.out.println("Public Key:");
            System.out.println(cert.getPublicKey());

            /* Here it prints the private key*/
            System.out.println("\nPrivate Key:");
            System.out.println(key);

            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,cert.getPublicKey());

            String cleartextFile = "C:\\email.txt";
            String ciphertextFile = "D:\\ciphertextRSA.png";

            FileInputStream fis = new FileInputStream(cleartextFile);
            FileOutputStream fos = new FileOutputStream(ciphertextFile);
            CipherOutputStream cos = new CipherOutputStream(fos, cipher);

            byte[] block = new byte[32];
            int i;
            while ((i = fis.read(block)) != -1) {
                cos.write(block, 0, i);
            }
            cos.close();


            /* computing the signature*/
            Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
            dsa.initSign(key);
            FileInputStream f = new FileInputStream(ciphertextFile);
            BufferedInputStream in = new BufferedInputStream(f);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) >= 0) {
               dsa.update(buffer, 0, len);
           };
           in.close();

           /* Here it prints the signature*/
           System.out.println("Digital Signature :");
           System.out.println( dsa.sign());

           /* Now Exporting Certificate */
           System.out.println("Exporting Certificate. ");
           byte[] buffer_out = cert.getEncoded();
           FileOutputStream os = new FileOutputStream(new File("d:\\signedcetificate.cer"));
           os.write(buffer_out);
           os.close();

           /* writing signature to output.dat file */
           byte[] buffer_out1 = dsa.sign();
           FileOutputStream os1 = new FileOutputStream(new File("d:\\output.dat"));
           os1.write(buffer_out1);
           os1.close();

       } catch (Exception e) {System.out.println(e);}

   }
}
4

4 に答える 4

11

キーストア ファイル (おそらく で終わる.jks) からjava.security.KeyStoreオブジェクトに読み込む必要があります。

/**
 * Reads a Java keystore from a file.
 * 
 * @param keystoreFile
 *          keystore file to read
 * @param password
 *          password for the keystore file
 * @param keyStoreType
 *          type of keystore, e.g., JKS or PKCS12
 * @return the keystore object
 * @throws KeyStoreException
 *           if the type of KeyStore could not be created
 * @throws IOException
 *           if the keystore could not be loaded
 * @throws NoSuchAlgorithmException
 *           if the algorithm used to check the integrity of the keystore
 *           cannot be found
 * @throws CertificateException
 *           if any of the certificates in the keystore could not be loaded
 */
public static KeyStore loadKeyStore(final File keystoreFile,
    final String password, final String keyStoreType)
    throws KeyStoreException, IOException, NoSuchAlgorithmException,
    CertificateException {
  if (null == keystoreFile) {
    throw new IllegalArgumentException("Keystore url may not be null");
  }
  LOG.debug("Initializing key store: {}", keystoreFile.getAbsolutePath());
  final URI keystoreUri = keystoreFile.toURI();
  final URL keystoreUrl = keystoreUri.toURL();
  final KeyStore keystore = KeyStore.getInstance(keyStoreType);
  InputStream is = null;
  try {
    is = keystoreUrl.openStream();
    keystore.load(is, null == password ? null : password.toCharArray());
    LOG.debug("Loaded key store");
  } finally {
    if (null != is) {
      is.close();
    }
  }
  return keystore;
}

KeyStoreを入手したら、Certificate公開鍵と秘密鍵を入手できます。

しかし、それを使用してテキストに署名し、ファイルに保存することは、より複雑であり、間違いを犯しやすい. Sign string using given Public Keyを見て、getKeyPairメソッドをKeyStore. の線に沿った何か

public static KeyPair getKeyPair(final KeyStore keystore, 
    final String alias, final String password) {
  final Key key = (PrivateKey) keystore.getKey(alias, password.toCharArray());

  final Certificate cert = keystore.getCertificate(alias);
  final PublicKey publicKey = cert.getPublicKey();

  return KeyPair(publicKey, (PrivateKey) key);
}

(明らかに少し粗いです。手元にサンプルがありませんでした)

于 2013-11-09T22:05:59.317 に答える
1
trusted.load(in, ((PBCApplication) context.getApplicationContext()).getBuildSettings().getCertificatePass());
Enumeration enumeration = trusted.aliases();

while (enumeration.hasMoreElements()) {
    String alias = (String) enumeration.nextElement();
    System.out.println("alias name: " + alias);
    Certificate certificate = trusted.getCertificate(alias);
    certificate.getPublicKey();
}
于 2014-08-30T12:06:48.243 に答える
0

私は Java コードを頭の片隅に保管していませんが、いくつかの一般的な健全性チェックは次のとおりです。

  • 必要な場所に保存したい公開証明書はありますか? 特に、私の記憶では、公開鍵と秘密鍵を含む証明書が 1 つのエイリアスの下に一緒に保存されているため、そこにある 2 つのエイリアス設定は非常に奇妙に思えます。両方を同じエイリアスで保存し、秘密鍵と公開鍵の両方の呼び出しで参照してみてください。

  • 証明書から何か他のものを取得できますか? たとえば、サブジェクト DN または発行者 DN はどちらも証明書の必須フィールドです。これにより、証明書が期待どおりに読み取られていることの良い証拠が得られます。

  • ほとんどすべての暗号トランザクションでは、ファイルからの読み取り方法とエンコード方式の転送方法に十分注意してください。ファイル IO を作成し、そこから奇妙な方法でプルした場合、キー マテリアルのエンコーディングが破損する可能性があります。これは最後に確認することです。通常、Java と JKS はそれほど悪くはありませんが、実際に発生します。同様に、ファイルの形式についても明確にしてください。たとえば、JKS ファイルは PKCS 12 ファイルとは異なります。

于 2013-11-12T15:43:55.280 に答える