【问题标题】:How to correctly encode DH parameters using BouncyCastle in Java?如何在 Java 中使用 BouncyCastle 正确编码 DH 参数?
【发布时间】:2011-04-27 10:28:17
【问题描述】:

我正在尝试在 Java 中以编程方式重现“openssl dhparam -out dh1024.pem 1024”命令的输出。代码 sn -p 如下:-

            DHParametersGenerator generator = new DHParametersGenerator();
            generator.init(1024, 0, new SecureRandom());
            DHParameters params = generator.generateParameters();
            // Generator G is set as random in params, but it has to be 2 to conform to openssl
            DHParameters realParams = new DHParameters(params.getP(), BigInteger.valueOf(2));

            byte[] p = realParams.getP().toByteArray();
            byte[] g = realParams.getG().toByteArray();
            byte[] l = new byte[(byte) realParams.getL()];
            byte[] pgl = new byte[p.length+g.length+l.length];

            System.arraycopy(p, 0, pgl, 0, p.length);
            System.arraycopy(g, 0, pgl, p.length, g.length);
            System.arraycopy(l, 0, pgl, p.length+g.length, l.length);

所以基本上我将 P、G 和 L 参数的值连接到一个字节数组“pgl”中,然后使用 BC 的 PEMWriter 类将其保存在一个文件中。但是当我尝试通过 openssl 使用它时,出现以下错误:-

无法从 /etc/openvpn/easy-rsa/keys/dh1024.pem: 错误:0D07207B:asn1 编码 例程:ASN1_get_object:header 太 长:错误:0D068066:asn1编码 例程:ASN1_CHECK_TLEN:坏对象 标头:错误:0D07803A:asn1 编码 例程:ASN1_ITEM_EX_D2I:嵌套 asn1 错误:错误:0906700D:PEM 例程:PEM_ASN1_read_bio:ASN1 库

.... 这让我相信我错误地编码了 DH 参数,但我找不到任何正确的编码方法。任何人都可以帮助我吗?很多天以来,我的头一直在城堡墙上弹跳,但无济于事....请帮忙:(

【问题讨论】:

  • 显然只是将它们连接起来是行不通的,因为任何程序怎么会知道一个参数在哪里结束,下一个参数从哪里开始?

标签: java security bouncycastle cryptoapi


【解决方案1】:

这是一个例子。请注意,您不能在 generator.init() 中将确定性参数设置为 0,否则您将无法获得质数!大部分代码我只是通过查看 Bouncycastle 源代码才知道的,例如查看 PEMWriter 类。

import java.math.BigInteger;
import java.security.SecureRandom;

import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.crypto.generators.DHParametersGenerator;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.util.encoders.Base64;

public class OpenSSLDHParamClone
{

    public static void main(String[] args) throws Exception
    {
        DHParametersGenerator generator = new DHParametersGenerator();
        generator.init(1024, 80, new SecureRandom());
        DHParameters params = generator.generateParameters();
        // Generator G is set as random in params, but it has to be 2 to conform to openssl
        DHParameters realParams = new DHParameters(params.getP(), BigInteger.valueOf(2));
        ASN1EncodableVector seq = new ASN1EncodableVector();
        seq.add(new DERInteger(realParams.getP()));
        seq.add(new DERInteger(realParams.getG()));
        byte [] derEncoded = new DERSequence(seq).getDEREncoded();
        System.out.println("-----BEGIN DH PARAMETERS-----");
        String b64Encoded = new String(Base64.encode(derEncoded), "US-ASCII");
        while (b64Encoded.length() > 0) {
            int subStringLength = Math.min(64, b64Encoded.length());
            System.out.println(b64Encoded.substring(0, subStringLength));
            b64Encoded = b64Encoded.substring(subStringLength);
        }
        System.out.println("-----END DH PARAMETERS-----");
    }
}

【讨论】:

    【解决方案2】:

    感谢 GregS,您的解决方案有效,但我最终使用标准 Java 和 BC 的 PemWriter 解决了它,虽然您无法使用这种方法设置生成器 G = 2,但它仍然适用于 openssl 和 Java,这是我最初的目的无论如何:)

    import java.io.FileWriter;
    import java.io.IOException;
    import java.security.AlgorithmParameterGenerator;
    import java.security.AlgorithmParameters;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.SecureRandom;
    import org.bouncycastle.util.io.pem.PemObject;
    import org.bouncycastle.util.io.pem.PemWriter;
    
    public class DHCredentials {
    
        public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, IOException 
            {
            DHCredentials dhc = new DHCredentials();
            System.out.println("This may take a long time ...");
    
            dhc.saveDHParams("C:\\xxxDH.txt", dhc.genDHParams());
    
            System.out.println("Done");
        }
    
        public byte[] genDHParams() throws IOException
        {
            AlgorithmParameterGenerator paramGen = null;
            try 
            {
                paramGen = AlgorithmParameterGenerator.getInstance("DH");
                paramGen.init(1024, new SecureRandom());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            AlgorithmParameters params = paramGen.generateParameters();
            return params.getEncoded();
        }
    
        public void saveDHParams(String filePath, byte[] DEREncodedDHParams)
        {
            PemWriter pemWrt;
    
            try {
                pemWrt = new PemWriter(new FileWriter(filePath));
                pemWrt.writeObject(new PemObject("DH PARAMETERS", DEREncodedDHParams));
                pemWrt.flush();
                pemWrt.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-11
      • 1970-01-01
      • 2020-02-01
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 2017-10-18
      • 2011-02-19
      相关资源
      最近更新 更多