我已经创建了一个小程序来使用Bouncy Castle 1.47 API生成一个DSA/El Gamal PGP钥匙环。密钥生成过程非常顺利,没有一个错误。我使用ARRAMED输出将私钥和公钥导出到一个文件,当我尝试用GPG(确切地说是KGpg)导入生成的私钥时,我得到以下错误:
[GNUPG:] NODATA 1
[GNUPG:] IMPORT_OK 17 1277C25B455C71D91EE42C8FF9A6087305C00DA6
[GNUPG:] IMPORTED F9A6087305C00DA6 test@gmail.com
[GNUPG:] IMPORT_OK 1 1277C25B455C71D91EE42C8FF9A6087305C00DA6
[GNUPG:] IMPORT_RES 1 0 1 0 0 0 0 0 0 1 1 0 0 0
单击OK后,它告诉我只处理了1个密钥。看起来它只拿了DSA键,因为在屏幕上它显示为1024/0。
**编辑**我刚刚尝试在Windows上打开PGP 10.1.0中的密钥,它也给我一个错误“密钥环包含一个坏的(损坏的)PGP数据包。”
我正在使用的代码如下所示,第一个是实用程序类,第二个是调用它来创建键的程序。
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, "test@gmail.com", "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();
}
}
生成的输出是两个文件“secret.asc”和“public.asc”,如果我尝试在GPG中导入“secret.asc”,我会出现错误,并且El Gamal子密钥无法导入。
有人知道这会有什么问题吗?
我设法解决了我自己的问题。我需要在最后显式关闭输出流。不这样做将导致数据损坏。
其次,作为额外的奖励,如果我使用rfc3526中列出的安全素数(素数模),它允许我生成不同比特大小长度的El Gamal密钥。
我想使用生成随机密钥,但java不支持填充,在我的算法中,我必须使用相同的填充,弹性城堡确实支持,但我无法理解如何使用它生成密钥 我的代码: 我收到的错误没有这样的算法
使用PEM证书,如 我的问题是,AFAIK,pemparser中没有密码的位置。 有人能给我一个如何将代码迁移到PEMParser版本的例子吗?
长话短说:我需要使用加密来对编码的数字执行乘法运算。 我目前正在使用与配合使用,并为JCE找到了一个名为Bouncy Castle的很好的提供程序。它在标准的内提供加密。然而,我完全不知道如何对我从中得到的加密消息执行乘法运算。
我知道曲线名称()以及EC公钥的和坐标。 如何用它们创建? 我读过https://stackoverflow.com/a/29355749/5453873,但是那里的代码使用而不是,ECPublicKey是中的接口,而不是一个可实例化的类。
Ladar Levison编写了ecies_encrypt和ecies_decrypt C函数。这些功能与ECIES弹力城堡兼容吗?如果不是,有没有人知道要修复什么或者ecies的另一个C实现?
我有一个自签名证书(不是流行的X.509证书)。证书和ECDSA公钥/私钥对由java程序使用bouncy Castle生成。我需要使用OpenSSL用C程序验证这个证书。然而,java程序可以正确地验证ECDSA签名,但openssl验证失败。如果我使用相同的私钥用openssl对消息重新签名,那么使用openssl的签名验证将通过。 下面是与密钥生成相关的java代码片段(生成密钥对后,我实际