Java 有人能帮我用BouncyCastle实现扩展主题的替代名称吗?

Java 有人能帮我用BouncyCastle实现扩展主题的替代名称吗?,java,certificate,x509certificate,bouncycastle,subject-alternative-name,Java,Certificate,X509certificate,Bouncycastle,Subject Alternative Name,我有一些字符串,用逗号分隔。我必须为Subject Alternative Names extension添加与任何GeneralName匹配的所有扩展名。有人能帮我完成这个循环吗 @Override public boolean saveKeypair(String arg0) { KeyPair keyPair = generateKeyPair(Integer.parseInt(access.getPublicKeyParameter())); PrivateK

我有一些字符串,用逗号分隔。我必须为Subject Alternative Names extension添加与任何GeneralName匹配的所有扩展名。有人能帮我完成这个循环吗

    @Override
public boolean saveKeypair(String arg0) {

    KeyPair keyPair = generateKeyPair(Integer.parseInt(access.getPublicKeyParameter()));

    PrivateKey privateKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    X500Name name = new X500Name(access.getSubject());
    BigInteger serial = new BigInteger(access.getSerialNumber());
    Date notBefore = access.getNotBefore();
    Date notAfter = access.getNotAfter();
    X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(name, serial, notBefore, notAfter, name,
            publicKey);

    // BEGIN extensions
    // certificate policies
    boolean isCritPol = access.isCritical(3);
    PolicyInformation[] policies = new PolicyInformation[1];
    policies[0] = new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.2.1.11.5"),
            new DERSequence(new PolicyQualifierInfo(access.getCpsUri())));
    try {
        certBuilder.addExtension(Extension.certificatePolicies, isCritPol, new CertificatePolicies(policies));
    } catch (CertIOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    // END CP

    // subject alternative name
    List<GeneralName> altNames = new ArrayList<GeneralName>();
    String [] altSubNames = access.getAlternativeName(5);

    for(String altName : altSubNames){
        // I NEED THIS LOOP, AND I DON'T KNOW HOW TO DO IT
    }

    // END SAN

    // END extensions


    try {
        // Content Signer
        Security.addProvider(new BouncyCastleProvider());
        ContentSigner sigGen = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(providerName)
                .build(privateKey);

        // Certificate
        X509Certificate certificate = new JcaX509CertificateConverter().setProvider(providerName)
                .getCertificate(certBuilder.build(sigGen));

     certificate.verify(publicKey);

        X509Certificate[] chain = new X509Certificate[1];       
        chain[0] = certificate;
        keyStore.setKeyEntry(arg0, privateKey, password.toCharArray(), chain);

    } catch (OperatorCreationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CertificateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SignatureException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (KeyStoreException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return true;
}

// BEGIN of functions for saveKeypair

public KeyPair generateKeyPair(int keySize) {
    KeyPair keyPair = null;

    try {
        KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(algorithm);
        keyGenerator.initialize(keySize);
        keyPair = keyGenerator.generateKeyPair();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    return keyPair;
}



// END of functions for saveKeypair
@覆盖
公共布尔存储密钥对(字符串arg0){
KeyPair KeyPair=generateKeyPair(Integer.parseInt(access.getPublicKeyParameter());
PrivateKey PrivateKey=keyPair.getPrivate();
PublicKey PublicKey=keyPair.getPublic();
X500名称=新的X500名称(access.getSubject());
BigInteger序列=新的BigInteger(access.getSerialNumber());
Date notBefore=access.getNotBefore();
Date notAfter=access.getNotAfter();
X509v3CertificateBuilder certBuilder=新JcaX509v3CertificateBuilder(名称、序列号、不在前、不在后、名称、,
公钥);
//开始扩展
//证书策略
布尔值isCritPol=access.isCritical(3);
PolicyInformation[]策略=新策略信息[1];
策略[0]=新的策略信息(新的ASN1ObjectIdentifier(“2.16.840.1.101.2.1.11.5”),
新的DERSequence(新的PolicyQualifierInfo(access.getCpsUri());
试一试{
certBuilder.addExtension(Extension.CertificatePolicys、isCritPol、新的CertificatePolicys(Policys));
}捕获(认证例外e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}
//结束CP
//主题替代名称
List altNames=new ArrayList();
字符串[]altSubNames=access.getAlternativeName(5);
用于(字符串altName:altSubNames){
//我需要这个循环,但我不知道怎么做
}
//端山
//端部延伸
试一试{
//内容签名者
addProvider(新的BouncyCastleProvider());
ContentSigner sigGen=new JcaContentSignerBuilder(signatureAlgorithm).setProvider(providerName)
.建造(私钥);
//证书
X509Certificate证书=新的JcaX509CertificateConverter().setProvider(providerName)
.getCertificate(certBuilder.build(sigGen));
验证证书(公钥);
X509Certificate[]链=新的X509Certificate[1];
链[0]=证书;
setKeyEntry(arg0,privateKey,password.toCharArray(),chain);
}捕获(操作员创建异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(证书例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(InvalidKeyException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(无算法异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(无此提供异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(签名例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(KeyStoreException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回true;
}
//saveKeypair的函数开始
公钥对生成器密钥对(int-keySize){
KeyPair KeyPair=null;
试一试{
KeyPairGenerator keyGenerator=KeyPairGenerator.getInstance(算法);
keyGenerator.initialize(keySize);
keyPair=keyGenerator.generateKeyPair();
}捕获(无算法异常){
e、 printStackTrace();
}
返回键对;
}
//saveKeypair的函数结束
该函数的其余部分正在工作

我正在Java中使用BouncyCastle
altSubName
是一些字符串的数组。并且应该以某种方式检查这些字符串是SubjectAlternativeName中的哪一个,并且应该添加包含所有通用名称的扩展名。

根据,Subject Alternative Name扩展名的一些字段具有定义的格式:

  • RFC822名称:格式在中定义
  • IP地址:在中定义
  • dnsName:
等等(看看RFC5280链接,它非常详细)

因此,要知道每个
字符串对应的字段是什么,必须检查每个字段中是否定义了格式

对于
rfc822Name
我找到了这个怪物正则表达式:

String rfc822Regex = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
String s = "test_ad.fade@mail.com";
if (s.matches(rfc822Regex)) {
    // is valid email
}
对于其他字段,可以搜索每个特定格式的正则表达式。我认为唯一的问题是
otherName
字段,因为它可以有任何格式(必须为每个证书颁发机构指定):

无论如何,通用代码如下所示(假设您已经搜索了如何验证每个特定格式):

然后将扩展添加到
certBuilder

GeneralNames subjectAltNames = GeneralNames.getInstance(new DERSequence((GeneralName[]) altNames.toArray(new GeneralName[] {})));
certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);

有人能帮我完成这个循环吗??我们不是你的远程编程工具,你自己完成吧。停止使用StackOverflow作为懒惰的捷径。我并不懒惰,我尝试了一些不正确的方法。我可以发布我不正确的函数,然后这个问题就可以了?我真的需要你的帮助。因为我在互联网上找到的所有东西都是关于只添加一个备选名称。我有一个想法,那就是使用regex并检查备选名称的类型,我很感兴趣是否有更好的解决方案?通用名称可以有很多不同的类型(dnsName、ipAddress、rfc822name等等),你知道你的弦应该是什么吗?你说“字符串应该以某种方式检查它们是哪个SubjectAlternativeName”-你有一些字符串的例子以及它们的类型是如何决定的吗?你使用的是什么版本的BouncyCastle?非常感谢!你知道一些其他通用名称的正则表达式吗?不幸的是,我不知道,但应该不难找到(它们都是非常有名的标准,甚至BouncyCastle也有,但我不确定)
// check the format and add with the correct field type
if (isValidEmail(altName)) {
    altNames.add(new GeneralName(GeneralName.rfc822Name, "user@mail.com"));
} else if (isValidDnsName(altName)) {
    altNames.add(new GeneralName(GeneralName.dNSName, "test.com"));
} else if (isValidIpAddress(altName)) {
    altNames.add(new GeneralName(GeneralName.iPAddress, "127.0.0.1"));
}
// ... and so on, for all GeneralName types
GeneralNames subjectAltNames = GeneralNames.getInstance(new DERSequence((GeneralName[]) altNames.toArray(new GeneralName[] {})));
certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);