从链中删除根 ca(签名)
Remove root ca from a chain (Signature)
我需要从证书链中删除根 ca。最好的方法是什么?我找到了读取值的方法,但无法删除它们。
你没有说清楚你想要什么,但这里有一个简单的例子来删除所有显示为自签名的证书(相同的颁发者和主题名称 - 最好实际验证签名,随意添加该代码)来自用于传送证书链的特殊 CMS 结构。此代码使用 Bouncycastle PKIX 库,但可以仅使用 Bouncycastle 核心库再多几行代码来完成此操作。
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.util.CollectionStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.function.Predicate;
public class PKCS7Certs {
private static final String P7_CERT_FILENAME = "stackexchange-com-chain.p7b";
private static final String OUT_FILENAME = "stackexchange-com-chain-no-root.p7b";
public static void main(String[] args) throws Exception {
Path p7In = Paths.get(P7_CERT_FILENAME);
Path p7Out = Paths.get(OUT_FILENAME);
removeRoot(p7In, p7Out);
}
private static void removeRoot(Path p7In, Path p7Out) throws Exception{
CMSSignedData contentInfo = new CMSSignedData(Files.newInputStream(p7In));
Collection<X509CertificateHolder> certs = contentInfo.getCertificates().getMatches(null);
// Delete the root cert(s)
certs.removeIf(new Predicate<X509CertificateHolder>() {
@Override
public boolean test(X509CertificateHolder cert) {
return ! cert.getIssuer().equals(cert.getSubject());
}
});
// create a new SignedData ContentInfo with the non-root certs
CollectionStore newStore = new CollectionStore(certs);
CMSSignedData newCI = CMSSignedData.replaceCertificatesAndCRLs(
contentInfo,
newStore,
contentInfo.getAttributeCertificates(),
contentInfo.getCRLs()
);
Files.write(p7Out, newCI.getEncoded());
}
}
从签名中删除根 ca 的其他可能性:
private byte[] removeRoot(byte[] b) throws CMSException, IOException {
CMSSignedData signature = new CMSSignedData(b);
Store<X509CertificateHolder> cs = signature.getCertificates();
Collection<X509CertificateHolder> certificates = cs.getMatches(new Selector<>() {
@Override
public boolean match(final X509CertificateHolder obj) {
return !Objects.equals(obj.getIssuer(), obj.getSubject());
}
@Override
public Object clone() {
return null;
}
});
final CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
generator.addSigners(signature.getSignerInfos());
generator.addAttributeCertificates(signature.getAttributeCertificates());
certificates.forEach(o -> {
try {
generator.addCertificate(o);
} catch (CMSException e) {
throw new RuntimeException(e);
}
});
CMSSignedData signedData = generator.generate(signature.getSignedContent(), true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ASN1InputStream asn1 = new ASN1InputStream(signedData.getEncoded())) {
DEROutputStream dos = new DEROutputStream(out);
dos.writeObject(asn1.readObject());
}
return out.toByteArray();
}
我需要从证书链中删除根 ca。最好的方法是什么?我找到了读取值的方法,但无法删除它们。
你没有说清楚你想要什么,但这里有一个简单的例子来删除所有显示为自签名的证书(相同的颁发者和主题名称 - 最好实际验证签名,随意添加该代码)来自用于传送证书链的特殊 CMS 结构。此代码使用 Bouncycastle PKIX 库,但可以仅使用 Bouncycastle 核心库再多几行代码来完成此操作。
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.util.CollectionStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.function.Predicate;
public class PKCS7Certs {
private static final String P7_CERT_FILENAME = "stackexchange-com-chain.p7b";
private static final String OUT_FILENAME = "stackexchange-com-chain-no-root.p7b";
public static void main(String[] args) throws Exception {
Path p7In = Paths.get(P7_CERT_FILENAME);
Path p7Out = Paths.get(OUT_FILENAME);
removeRoot(p7In, p7Out);
}
private static void removeRoot(Path p7In, Path p7Out) throws Exception{
CMSSignedData contentInfo = new CMSSignedData(Files.newInputStream(p7In));
Collection<X509CertificateHolder> certs = contentInfo.getCertificates().getMatches(null);
// Delete the root cert(s)
certs.removeIf(new Predicate<X509CertificateHolder>() {
@Override
public boolean test(X509CertificateHolder cert) {
return ! cert.getIssuer().equals(cert.getSubject());
}
});
// create a new SignedData ContentInfo with the non-root certs
CollectionStore newStore = new CollectionStore(certs);
CMSSignedData newCI = CMSSignedData.replaceCertificatesAndCRLs(
contentInfo,
newStore,
contentInfo.getAttributeCertificates(),
contentInfo.getCRLs()
);
Files.write(p7Out, newCI.getEncoded());
}
}
从签名中删除根 ca 的其他可能性:
private byte[] removeRoot(byte[] b) throws CMSException, IOException {
CMSSignedData signature = new CMSSignedData(b);
Store<X509CertificateHolder> cs = signature.getCertificates();
Collection<X509CertificateHolder> certificates = cs.getMatches(new Selector<>() {
@Override
public boolean match(final X509CertificateHolder obj) {
return !Objects.equals(obj.getIssuer(), obj.getSubject());
}
@Override
public Object clone() {
return null;
}
});
final CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
generator.addSigners(signature.getSignerInfos());
generator.addAttributeCertificates(signature.getAttributeCertificates());
certificates.forEach(o -> {
try {
generator.addCertificate(o);
} catch (CMSException e) {
throw new RuntimeException(e);
}
});
CMSSignedData signedData = generator.generate(signature.getSignedContent(), true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ASN1InputStream asn1 = new ASN1InputStream(signedData.getEncoded())) {
DEROutputStream dos = new DEROutputStream(out);
dos.writeObject(asn1.readObject());
}
return out.toByteArray();
}