EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Decrypt XML error 34128

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#34893
Posted: 10/26/2015 14:42:21
by Rafael Deitos (Basic support level)
Joined: 09/22/2015
Posts: 1

I am using the example "Simple Encryption". Adapted to decrypt XML using "smart card".
Create a TElXMLDecryptor and TElXMLKeyInfoX509Data, load the xml, the certificate in step X509KeyData.Certificate.
When I run Decryptor.Decrypt(FXMLDocument), get the following error 34128

Code
procedure TfrmMain.Button1Click(Sender: TObject);
var
  Decryptor: TElXMLDecryptor;
  SymKeyData, SymKEKData: TElXMLKeyInfoSymmetricData;
  RSAKeyData: TElXMLKeyInfoRSAData;
  X509KeyData: TElXMLKeyInfoX509Data;
  PGPKeyData: TElXMLKeyInfoPGPData;
  ArquivoStream:TFileStream;
  Node, T: TElXMLDOMNode;
  i: Integer;
  Cert : TElX509Certificate;
begin
  if Assigned(tvXML.Selected) and
     Assigned(tvXML.Selected.Data) then
    Node := TElXMLDOMNode(tvXML.Selected.Data)
  else
    Node := TElXMLDOMNode(FXMLDocument);

  while (Node is TElXMLDOMElement) and
        (TElXMLDOMElement(Node).LocalName <> 'EncryptedData') and
        Assigned(Node.ParentNode) do
    Node := Node.ParentNode;

  if (Node is TElXMLDOMElement) and
     (TElXMLDOMElement(Node).LocalName = 'EncryptedData') and
     Assigned(Node.ParentNode) and
     (Node.ParentNode is TElXMLDOMDocument) then
    Node := Node.ParentNode;

  if Node is TElXMLDOMDocument then
    T := TElXMLDOMDocument(Node).DocumentElement
  else
    T := Node;

  if (not (T is TElXMLDOMElement) or
     (TElXMLDOMElement(T).LocalName <> 'EncryptedData')) then
  begin
    MessageDlg('Please, select EncryptedData element or Document for decryption.', mtInformation, [mbOK], 0);
    Exit;
  end;

  SymKeyData := nil;
  SymKEKData := nil;
  RSAKeyData := nil;
  X509KeyData := nil;
  PGPKeyData := nil;
  Decryptor := TElXMLDecryptor.Create(Self);
  try
    if cmbWindowsCertificates.ItemIndex > 0 then
    begin
      Cert := WinCertStorage.Certificates[cmbWindowsCertificates.ItemIndex - 1];
      CertStorage.Add(Cert);
    end;

    try
      if Node is TElXMLDOMDocument then
        Decryptor.Load(TElXMLDOMDocument(Node))
      else
        Decryptor.Load(TElXMLDOMElement(Node));
    except
      on E: Exception do
        raise EElXMLError.CreateFmt('Encrypted data loading failed. (%s)', [E.Message]);
    end;

    frmEnc.EncryptKey := Decryptor.EncryptKey;
    frmEnc.EncryptedDataType := Decryptor.EncryptedDataType;
    frmEnc.EncryptionMethod := Decryptor.EncryptionMethod;
    frmEnc.KeyEncryptionType := Decryptor.KeyEncryptionType;
    frmEnc.KeyTransportMethod := Decryptor.KeyTransportMethod;
    frmEnc.KeyWrapMethod := Decryptor.KeyWrapMethod;
    frmEnc.KeyName := Decryptor.KeyName;
    frmEnc.MimeType := Decryptor.MimeType;
    frmEnc.LockOpt := True;
    frmEnc.UpdateOpt;

    while True do
    begin
      if frmEnc.ShowModal = mrOK then
      begin
        if Decryptor.EncryptKey then
        begin
          if Decryptor.KeyEncryptionType = xetKeyWrap then
          begin
            SymKEKData := TElXMLKeyInfoSymmetricData.Create(True);

//            ArquivoStream := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
            try
//              SymKEKData.Key.Load(ArquivoStream);
            finally
//              FreeAndNil(ArquivoStream);
            end;

            Decryptor.KeyEncryptionKeyData := SymKEKData;
          end
          else
          begin
            FreeAndNil(RSAKeyData);
//            FreeAndNil(X509KeyData);
            FreeAndNil(PGPKeyData);
            RSAKeyData := TElXMLKeyInfoRSAData.Create(True);
            RSAKeyData.RSAKeyMaterial.Passphrase := frmEnc.Passphrase;
            X509KeyData := TElXMLKeyInfoX509Data.Create(True);
            PGPKeyData := TElXMLKeyInfoPGPData.Create(True);

//            ArquivoStream := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
            try
//              RSAKeyData.RSAKeyMaterial.LoadSecret(ArquivoStream);
            except
            end;

            if not RSAKeyData.RSAKeyMaterial.SecretKey then
            begin
//              ArquivoStream.Position := 0;
              LoadCertificate(ArquivoStream, frmEnc.Passphrase, X509KeyData);
            end;

            if not RSAKeyData.RSAKeyMaterial.PublicKey and
               not Assigned(X509KeyData.Certificate) then
            begin
              ArquivoStream.Position := 0;
              PGPKeyData.SecretKey := TElPGPSecretKey.Create;
              PGPKeyData.SecretKey.Passphrase := frmEnc.Passphrase;
              try

                TElPGPSecretKey(PGPKeyData.SecretKey).AssignFromX509(X509KeyData.Certificate);
              except
                PGPKeyData.SecretKey.Free;
                PGPKeyData.SecretKey := nil;
              end;
            end;
//            FreeAndNil(ArquivoStream);

            if RSAKeyData.RSAKeyMaterial.SecretKey then
              Decryptor.KeyEncryptionKeyData := RSAKeyData
            else
            if Assigned(X509KeyData.Certificate) then
              begin
                if X509KeyData.Certificate.PrivateKeyExists then
                  ShowMessage('Existe Privada');
                if X509KeyData.Certificate.PrivateKeyExtractable then
                  ShowMessage('Chave privada extraivel');
                if X509KeyData.Certificate.CanEncrypt then
                  ShowMessage('Pode Encriptar');

                Decryptor.KeyEncryptionKeyData := X509KeyData
              end
            else
            if Assigned(PGPKeyData.SecretKey) then
              Decryptor.KeyEncryptionKeyData := PGPKeyData
            else
              raise EElXMLError.Create('Key not loaded.');
          end;
        end
        else
        begin
          SymKeyData := TElXMLKeyInfoSymmetricData.Create(True);

          ArquivoStream := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
          try
            SymKeyData.Key.Load(ArquivoStream);
          finally
            FreeAndNil(ArquivoStream);
          end;

          Decryptor.KeyData := SymKeyData;
        end;

        i := Decryptor.Decrypt(FXMLDocument);
        if i <> SB_XML_ENC_ERROR_OK then
        begin
          if (not Decryptor.EncryptKey and (i = SB_XML_ENC_ERROR_INVALID_KEY)) or
             (Decryptor.EncryptKey and (i = SB_XML_ENC_ERROR_INVALID_KEK)) then
            MessageDlg('Decryption failed. Bad key or data is corrupted.', mtError, [mbOK], 0)
          else
            raise EElXMLError.CreateFmt('Decryption failed. Error code: 0x%x', [i]);

          Continue;
        end;

        if Decryptor.EncryptedDataType = xedtExternal then
        begin
          ArquivoStream := TFileStream.Create(frmEnc.ExternalFile, fmCreate);
          try
            if Length(Decryptor.DecryptedData) > 0 then
              ArquivoStream.Write(Decryptor.DecryptedData[0], Length(Decryptor.DecryptedData));
          finally
            FreeAndNil(ArquivoStream);
          end;

          MessageDlg('Data saved successfully.', mtInformation, [mbOK], 0);
        end
        else
        begin
          if Assigned(Decryptor.DecryptedNode) then
          begin
            if Node is TElXMLDOMDocument then
              FXMLDocument.ReplaceChild(Decryptor.DecryptedNode, FXMLDocument.DocumentElement)
            else
              Node.ParentNode.ReplaceChild(Decryptor.DecryptedNode, Node);

            Decryptor.DecryptedNode := nil;
          end
          else
          if (Decryptor.EncryptedDataType = xedtContent) and
             Assigned(Decryptor.DecryptedNodeList) then
          begin
            T := Node.ParentNode;
            for i := 0 to Decryptor.DecryptedNodeList.Length - 1 do
              T.InsertBefore(Decryptor.DecryptedNodeList.Item[i].CloneNode(True), Node);

            T.RemoveChild(Node);
          end;

          UpdateXML;
        end;

        Break;
      end
      else
        Break;
    end;

  finally
    CertStorage.Clear;
    FreeAndNil(ArquivoStream);
    FreeAndNil(Decryptor);
    FreeAndNil(SymKeyData);
    FreeAndNil(SymKEKData);
    FreeAndNil(RSAKeyData);
    FreeAndNil(X509KeyData);
    FreeAndNil(PGPKeyData);
  end;
end;
#34894
Posted: 10/26/2015 16:19:31
by Dmytro Bogatskyy (EldoS Corp.)

I've moved the question to the helpdesk for investigation ( https://www.eldos.com/helpdesk/ ). You will see your (and only your) support tickets by following this URL. You will also get e-mail notifications about updates related to your support ticket.

Reply

Statistics

Topic viewed 1654 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!