Delphi XE10.x实现Android下读取pfx证书

有一个简单的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.

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值