2012-12-05 1 views
2

Bouncy Castle 1.47 API를 사용하여 DSA/El Gamal PGP 키 링을 생성하는 작은 프로그램을 만들었습니다. 키 생성은 오류없이 실제로 실행됩니다.GPG에서 오류없이 가져 오는 탄력성있는 dsa/elgamal 키 쌍 생성

[GNUPG:] NODATA 1 
[GNUPG:] IMPORT_OK 17 1277C25B455C71D91EE42C8FF9A6087305C00DA6 
[GNUPG:] IMPORTED F9A6087305C00DA6 [email protected] 
[GNUPG:] IMPORT_OK 1 1277C25B455C71D91EE42C8FF9A6087305C00DA6 
[GNUPG:] IMPORT_RES 1 0 1 0 0 0 0 0 0 1 1 0 0 0 

후 나는 그것을 알려줍니다 확인을 클릭합니다 : 나는 다음과 같은 오류가 나는 장갑 출력을 사용하여 파일에 개인 및 공개 키를 내보내고 내가 GPG에 생성 된 개인 키를 가져올 때 (KGpg를 정확한 수) 나만 하나의 키만 처리되었다. 화면에 1024/0로 표시되므로 DSA 키만 사용 된 것처럼 보입니다.

** 편집 ** 난 그냥 Windows에서 PGP 10.1.0에서 키를 열리는 시도하고 또한 나에게 에 오류가 있습니다 "키 링이 나쁜 (손상) PGP 패킷을 포함합니다."

아래 코드는 Utility 클래스이고, 두 번째는 키를 생성하는 프로그램입니다.

package george.crypto.pgp; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.NoSuchAlgorithmException; 
import java.security.NoSuchProviderException; 
import java.security.Security; 
import java.util.Date; 

import org.bouncycastle.bcpg.ArmoredOutputStream; 
import org.bouncycastle.bcpg.HashAlgorithmTags; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.jce.spec.ElGamalParameterSpec; 
import org.bouncycastle.openpgp.PGPEncryptedData; 
import org.bouncycastle.openpgp.PGPKeyPair; 
import org.bouncycastle.openpgp.PGPKeyRingGenerator; 
import org.bouncycastle.openpgp.PGPPublicKey; 
import org.bouncycastle.openpgp.PGPPublicKeyRing; 
import org.bouncycastle.openpgp.PGPSecretKeyRing; 
import org.bouncycastle.openpgp.PGPSignature; 
import org.bouncycastle.openpgp.operator.PGPDigestCalculator; 
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; 
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; 
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; 

public final class PGPTools { 

    static { 
     Security.addProvider(new BouncyCastleProvider()); 
    } 

    private PGPTools() { 

    } 

    public static final void exportSecretKey(PGPKeyRingGenerator pgpKeyRingGen, File keyFile, boolean asciiArmor) throws IOException { 
     PGPSecretKeyRing pgpSecKeyRing = pgpKeyRingGen.generateSecretKeyRing(); 

     if(asciiArmor) { 
      pgpSecKeyRing.encode(new ArmoredOutputStream(new FileOutputStream(keyFile))); 
     } 
     else { 
      pgpSecKeyRing.encode(new FileOutputStream(keyFile)); 
     } 
    } 

    public static final void exportPublicKey(PGPKeyRingGenerator pgpKeyRingGen, File keyFile, boolean asciiArmor) throws IOException { 
     PGPPublicKeyRing pgpPubKeyRing = pgpKeyRingGen.generatePublicKeyRing(); 

     if(asciiArmor) { 
      pgpPubKeyRing.encode(new ArmoredOutputStream(new FileOutputStream(keyFile))); 
     } 
     else { 
      pgpPubKeyRing.encode(new FileOutputStream(keyFile)); 
     } 
    } 

    /** 
    * 
    * @param dsaKeyPair - the generated DSA key pair 
    * @param elGamalKeyPair - the generated El Gamal key pair 
    * @param identity - the given identity of the key pair ring 
    * @param passphrase - the secret pass phrase to protect the key pair 
    * @return a PGP Key Ring Generate with the El Gamal key pair added as sub key 
    * @throws Exception 
    */ 
    @SuppressWarnings("deprecation") 
    public static final PGPKeyRingGenerator createPGPKeyRingGenerator(KeyPair dsaKeyPair, KeyPair elGamalKeyPair, String identity, char[] passphrase) throws Exception 
    { 
     PGPKeyPair dsaPgpKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKeyPair, new Date()); 
     PGPKeyPair elGamalPgpKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elGamalKeyPair, new Date()); 
     PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); 
     PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaPgpKeyPair, identity, sha1Calc, null, null, new JcaPGPContentSignerBuilder(dsaPgpKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("BC").build(passphrase)); 
     keyRingGen.addSubKey(elGamalPgpKeyPair); 
     return keyRingGen; 
    } 

    /** 
    * 
    * @param keySize 512 - 1024 (multiple of 64) 
    * @return the DSA generated key pair 
    * @throws NoSuchProviderException 
    * @throws NoSuchAlgorithmException 
    */ 
    public static final KeyPair generateDsaKeyPair(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException 
    { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA", "BC"); 
     keyPairGenerator.initialize(keySize); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     return keyPair; 
    } 

    /** 
    * 
    * @param keySize - 1024, 2048, 4096 
    * @return the El Gamal generated key pair 
    * @throws Exception 
    */ 
    public static final KeyPair generateElGamalKeyPair(int keySize) throws Exception 
    { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ELGAMAL", "BC"); 
     keyPairGenerator.initialize(keySize); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     return keyPair; 
    } 

    /** 
    * 
    * @param paramSpecs - the pre-defined parameter specs 
    * @return the El Gamal generated key pair 
    * @throws Exception 
    */ 
    public static final KeyPair generateElGamalKeyPair(ElGamalParameterSpec paramSpecs) throws Exception 
    { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ELGAMAL", "BC"); 
     keyPairGenerator.initialize(paramSpecs); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     return keyPair; 
    } 
} 

package george.crypto.pgp; 

import java.io.File; 
import java.math.BigInteger; 
import java.security.KeyPair; 

import org.bouncycastle.jce.spec.ElGamalParameterSpec; 
import org.bouncycastle.openpgp.PGPKeyRingGenerator; 

public class PGPCryptoBC { 

    public PGPCryptoBC() { 
     try { 
      String keysDir = System.getProperty("user.dir")+File.separator+"src/george/crypto/pgp/keys"; 

      //Generating a safe prime is a very long process so it's better to use 
      //a pre-generated safe prime, I took this from http://www.cryptopp.com/fom-serve/cache/71.html 
      BigInteger primeModulous = new BigInteger("36F0255DDE973DCB3B399D747F23E32ED6FDB1F77598338BFDF44159C4EC64DDAEB5F78671CBFB22106AE64C32C5BCE4CFD4F5920DA0EBC8B01ECA9292AE3DBA1B7A4A899DA181390BB3BD1659C81294F400A3490BF9481211C79404A576605A5160DBEE83B4E019B6D799AE131BA4C23DFF83475E9C40FA6725B7C9E3AA2C6596E9C05702DB30A07C9AA2DC235C5269E39D0CA9DF7AAD44612AD6F88F69699298F3CAB1B54367FB0E8B93F735E7DE83CD6FA1B9D1C931C41C6188D3E7F179FC64D87C5D13F85D704A3AA20F90B3AD3621D434096AA7E8E7C66AB683156A951AEA2DD9E76705FAEFEA8D71A5755355970000000000000001", 16); 
      BigInteger baseGenerator = new BigInteger("2", 16); 
      ElGamalParameterSpec paramSpecs = new ElGamalParameterSpec(primeModulous, baseGenerator); 

      KeyPair dsaKeyPair = PGPTools.generateDsaKeyPair(1024); 
      KeyPair elGamalKeyPair = PGPTools.generateElGamalKeyPair(paramSpecs); 
      PGPKeyRingGenerator pgpKeyRingGen = PGPTools.createPGPKeyRingGenerator(dsaKeyPair, elGamalKeyPair, "[email protected]", "TestPass12345!".toCharArray()); 

      PGPTools.exportSecretKey(pgpKeyRingGen, new File(keysDir+File.separator+"secret.asc"), true); 
      PGPTools.exportPublicKey(pgpKeyRingGen, new File(keysDir+File.separator+"public.asc"), true); 
     } 
     catch(Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public static void main(String ... args) { 
     new PGPCryptoBC(); 
    } 
} 

생성 된 출력은 2 개 파일 "secret.asc"와 "public.asc"나는 GPG에 "secret.asc"를 가져 오려고하면 있습니다 내가 얻을 오류 및 엘 가말 서브 키 수입되지 않습니다.

누구에게이 문제가있을 수 있다는 것을 알고 있습니까?

답변

3

나는 내 자신의 문제를 해결할 수있었습니다. 끝에 출력 스트림을 명시 적으로 닫아야했습니다. 그렇게하지 않으면 데이터가 손상 될 수 있습니다.

둘째, 추가 보너스로 rfc3526에 나열된 Safe Prime (프라임 계수)을 사용하면 다양한 비트 크기의 El Gamal 키를 생성 할 수 있습니다.

관련 문제