有一个简单的pfx证书,证书链就两个
unit PKCS12Parser;
interface
uses Androidapi.JNIBridge,FMX.Dialogs,
bcprovext, System.SysUtils,
Androidapi.Helpers, bcpkix, //bctls,
Androidapi.JNI.Java.Security,
BCLibrary,
java.security.spec.PKCS8EncodedKeySpec,
Androidapi.JNI.JavaTypes;
type
TDorjePKCS12Parser = class
private
FJPublickey: JPublickey;
FJProvider: JProvider;
public
constructor Create;
function readPKCS12File(const pfxIn : JInputStream; const APassword: String):JPKCS12PfxPdu;
end;
implementation
constructor TDorjePKCS12Parser.Create;
begin
FJProvider := TDorjeSecurity.init;
end;
function TDorjePKCS12Parser.readPKCS12File(const pfxIn : JInputStream; const APassword: String):JPKCS12PfxPdu;
var
pfx : JPKCS12PfxPdu; //secure Protocol Data Unit (PDU).
certMap,
certKeyIds,
privKeyMap,
privKeyIds : JMap;
inputDecryptorProvider : JInputDecryptorProvider;
jcaConverter : JJcaX509CertificateConverter;
bagFactory : JPKCS12SafebagFactory;
bag : JPKCS12SafeBag;
bags : TJavaObjectArray<JPKCS12SafeBag>;
certHldr : JX509CertificateHolder;
cert : JX509Certificate;
attr : JAttribute;
infos : TJavaObjectArray<JContentInfo>;
encInfo : JPKCS8EncryptedPrivateKeyInfo;
info : JPrivateKeyInfo;
keyFact : JKeyFactory;
privKey : JPrivateKey;
attributes : TJavaObjectArray<JAttribute>;
pkcs12Provider : JPKCS12MacCalculatorBuilderProvider;
pwd: Jstring;
I, b, a: Integer;
begin
pwd := StringToJString(APassword);
pkcs12Provider := TJPKCS12MacCalculatorBuilderProvider.Wrap(TJBcPKCS12MacCalculatorBuilderProvider.JavaClass.init(TJBcDefaultDigestProvider.JavaClass.INSTANCE));
pfx := TJPKCS12PfxPdu.JavaClass.init(TJStreams.JavaClass.readAll(pfxIn));
if not pfx.isMacValid(pkcs12Provider, pwd.toCharArray) then
begin
ShowMessage('PKCS#12 MAC test failed!');
end;
infos := pfx.getContentInfos;
certMap := TJMap.Wrap(TJHashMap.Create);
certKeyIds := TJMap.Wrap(TJHashMap.Create);
privKeyMap := TJMap.Wrap(TJHashMap.Create);
privKeyIds := TJMap.Wrap(TJHashMap.Create);
inputDecryptorProvider := TJJcePKCSPBEInputDecryptorProviderBuilder.Create.setProvider(FJProvider).build(pwd.toCharArray);
jcaConverter := TJJcaX509CertificateConverter.Create.setProvider(FJProvider);
i := 0;
while ( i <> infos.length) do
begin
if infos[i].getContentType.equals(TJPKCSObjectIdentifiers.JavaClass.encryptedData) then
begin
bagFactory := TJPKCS12SafebagFactory.JavaClass.init(infos[i], inputDecryptorProvider);
bags := bagFactory.getSafeBags;
b := 0;
while (b <> bags.length) do
begin
bag := bags[b];
certHldr := TJX509CertificateHolder.Wrap(bag.getBagValue);
cert := jcaConverter.getCertificate(certHldr);
attributes := bag.getAttributes();
if attributes <> nil then
begin
a := 0;
while (a <> attributes.length) do
begin
attr := attributes[a];
if attr.getAttrType.equals(TJPKCS12SafeBag.JavaClass.friendlyNameAttribute) then
begin
certMap.put(TJDERBMPString.Wrap(attr.getAttributeValues[0]).getString, cert);
end
else
if attr.getAttrType.equals(TJPKCS12SafeBag.JavaClass.localKeyIdAttribute) then
begin
certKeyIds.put(TJObject.Wrap(attr.getAttributeValues[0]), TJObject.Wrap(cert));
end;
Inc(a);
end;
end;
Inc(b);
end;
end
else
begin
bagFactory := TJPKCS12SafebagFactory.JavaClass.init(infos[i]);
bags := bagFactory.getSafeBags;
encInfo := TJPKCS8EncryptedPrivateKeyInfo.Wrap(bags[0].getBagValue);
info := encInfo.decryptPrivateKeyInfo(inputDecryptorProvider);
keyFact := TJKeyFactory.JavaClass.getInstance(info.getPrivateKeyAlgorithm.getAlgorithm.getId, FJProvider);
privKey := keyFact.generatePrivate(TJKeySpec.Wrap(TJPKCS8EncodedKeySpec.JavaClass.init(info.getEncoded)));
attributes := bags[0].getAttributes;
a := 0;
while (a <> attributes.length) do
begin
attr := attributes[a];
if attr.getAttrType.equals(TJPKCS12SafeBag.JavaClass.friendlyNameAttribute) then
begin
privKeyMap.put(TJDERBMPString.Wrap(attr.getAttributeValues[0]).getString, TJObject.Wrap(privKey));
end
else
if attr.getAttrType.equals(TJPKCS12SafeBag.JavaClass.localKeyIdAttribute) then
begin
privKeyIds.put(TJObject.Wrap(privKey), TJObject.Wrap(attr.getAttributeValues[0]));
end;
Inc(a);
end;
end;
Inc(i);
end;
Exit(pfx);
end;
end.