Linux에서 xml 파일의 base64 텍스트를 디코딩하는 방법은 무엇입니까?

Linux에서 xml 파일의 base64 텍스트를 디코딩하는 방법은 무엇입니까?

저는 Linux (셸)를 처음 사용합니다. Linux 셸 스크립트를 사용하여 xml 파일의 base64 텍스트를 디코딩해야 합니다. 인코딩="base64" 속성을 사용하여 해당 태그의 값을 디코딩하는 Linux 쉘 스크립트를 작성하는 데 도움을 줄 수 있습니까? 내 파일 구조는 다음과 같습니다.

    <directory-entries>
        <entry dn="ads">
        <attr name="memberof">
        <value>CN=VPN-employee</value>
        <value encoding="base64">aGVsbG8gd29ybGQ=   </value>
<value encoding="base64">
Q049RmxvcHB5IC0g0LTQvtGB0YLRg9C/INC30LDQutGA0YvRgixPVT1EZXZpY2UgQ29udHJv
bCxPVT1Hcm91cHMsT1U90JHQkNCd0JosREM9aHEsREM9YmM=
    </value>
    <value encoding="base64">
Q049VVNCLdC00LjRgdC60LggLSDRgtC+0LvRjNC60L4g0YfRgtC10L3QuNC1LE9VPURldmlj
ZSBDb250cm9sLE9VPUdyb3VwcyxPVT3QkdCQ0J3QmixEQz1ocSxEQz1iYw==
    </value>
    </attr>
    </entry>
    </directory-entries>

원하는 출력은

    <directory-entries>
        <entry dn="ads">
        <attr name="memberof">
        <value>CN=VPN-employee</value>
        <value encoding="base64">Hello world  </value>
       <value encoding="base64"> decoded         </value>
       <value encoding="base64">    decoded         </value>
    </attr>
    </entry>
    </directory-entries>

Active Directory에서 XML을 생성하기 위해 ldapsearch를 사용하고 있습니다. 파일을 가져오는 데 사용하는 스크립트는 다음과 같습니다.

ldapsearch -h host -p 389 -D "CN=informatica,OU=Accounts for System Purposes,OU=System Accounts,DC=hq,DC=bc" -w password -s sub -B -E UTF-8 -X "(&(objectClass=organizationalPerson)(CN=*))" employeeID memberof > ldap_logins.xml

xml 파일을 생성하는 동안 텍스트를 디코딩하는 것이 가능한지 모르겠습니다. 미리 감사드립니다!

답변1

제가 평소에 무엇을 하는지 이야기해보겠습니다. XML을 구문 분석하는 데 정규식을 사용하지 마십시오. 이것은 나쁜 소식입니다. XML은 다양한 형식으로 제공됩니다. 이는 의미상 동일한 XML이 특정 정규식과 일치하거나 일치하지 않음을 의미합니다. 줄 바꿈, 단항 태그 등과 같은 간단한 것입니다.

이는 업스트림 데이터 흐름의 완벽하게 유효한 변경으로 인해 어느 날 알 수 없는 이유로 깨질 수 있는 취약한 코드를 생성한다는 의미입니다.

파싱을 위해당신의XML 사용을 권장 perl하며 꽤 좋습니다.XML::Twig기준 치수.

#!/usr/bin/perl
use strict;
use warnings;

use XML::Twig;
use MIME::Base64;

#we take a "value" element, check it for an "encoding=base64" and if it is
#we rewrite the content and delete that attribute in the XML. 
sub decode_value {
    my ( $twig, $value ) = @_;
    if (    $value->att('encoding')
        and $value->att('encoding') eq "base64" )
    {
        my $decoded_text = decode_base64( $value->text );
        if ( $decoded_text =~ m/[^\s\d\w\=\-\,\.]/ ) {
            $decoded_text = "decoded";
        }
        $value->set_text($decoded_text);
        $value -> del_att('encoding');

    }
}


#twig handlers 'fires' a piece of code each time you hit a 'value' element. 
#it passes this piece of code that chunk of XML to handle, which means
#you can do things like dynamic XML rewrites 
#pretty print controls output XML rendering - there's a variety of options
#check the manpage. 
my $twig = XML::Twig->new(
    pretty_print  => "indented",
    twig_handlers => { 'value' => \&decode_value, }
);
$twig->parsefile('your_xml_file');
$twig->print;

그러면 다음이 제공됩니다.

<directory-entries>
  <entry dn="ads">
    <attr name="memberof">
      <value>CN=VPN-employee</value>
      <value encoding="base64">hello world</value>
      <value encoding="base64">decoded</value>
      <value encoding="base64">decoded</value>
    </attr>
  </entry>
</directory-entries>

다음과 같이 변환 할 수도 있습니다 $decoded_text.

$decoded_text =~ s/[^\s\d\w=,-. ]+/_/g;

( URI::Escape여기에 있는 모듈은 텍스트 URL 스타일을 "퍼센트 인코딩"하므로 살펴볼 가치가 있습니다.)

그러면 다음이 제공됩니다.

  <value encoding="base64">CN=Floppy - _ _,OU=Device Control,OU=Groups,OU=_,DC=hq,DC=bc</value>
  <value encoding="base64">CN=USB-_ - _ _,OU=Device Control,OU=Groups,OU=_,DC=hq,DC=bc</value>

Net::LDAP그러나 용도를 사용하면 요구 사항이 충족될 수도 있습니다 .

#!/usr/bin/perl
use strict;
use warnings;

use Net::LDAP;

my $ldap   = Net::LDAP->new('host');
my $result = $ldap->bind(
    'CN=informatica,OU=Accounts for System Purposes,OU=System Accounts,DC=hq,DC=bc',
    'password'
);
if ( $result->code ) { die "Error connecting to LDAP server"; }

my $ldap_search = $ldap->search(
    base   => 'DC=hq,DC=bc',
    scope  => 'subtree',
    filter => '(&(objectClass=organizationalPerson)(CN=*))',
    attrs  => [ 'employeeID', 'memberOf' ],
);

foreach my $entry ( $ldap_search->entries ) {
    print "dn:\t", $entry->dn(), "\n";
    foreach my $attr ( $entry->attributes ) {
        print "$attr:";
        foreach my $value ( $entry->get_value($attr) ) {
            next unless defined $value;
            if ( $value =~ m/[^\s\d\w,-=+@\'.()]/ ) { $value = "binary_data" }
            chomp($value);
            print "\t$value\n";
        }
    }
}

답변2

컴팩트 스크립트

xml이 에 있다고 가정하고 file.xml다음을 수행하십시오.

sed -r 's/("base64">)([[:graph:]]+)/\1'"`grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d`"'/g' file.xml 

다음은 작업을 수행하는 간단한 정규식입니다. 분해해서 설명하겠습니다.

무너지다

먼저 grep을 사용하여 Base64 문자열을 선택하고 디코딩합니다.

grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d

변수에 저장할 수 있습니다.

baseString=`grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d`

그런 다음 sedbase64를 변수에 저장된 디코딩된 문자열로 바꿉니다.

sed -r 's/("base64">)([[:graph:]]+)/\1'"$baseString"'/g' file.xml

답변3

를 사용하는 것이 정답입니다 xmlstarlet. 이것은 XML 구문 분석 및 편집을 위한 도구입니다. 먼저 이 패키지를 시스템에 설치하십시오. Debian 기반 시스템을 사용하는 경우 다음을 수행하십시오.

sudo apt-get install xmlstarlet

지금,

  1. 먼저 base64로 인코딩된 문자열의 값을 읽습니다.
  2. 그런 다음 이 문자열을 디코딩합니다.
  3. 그런 다음 해당 태그 값을 수정합니다.

전체 스크립트는 다음과 같습니다.

#!/bin/bash

for i in $(seq 3)
do
    #Find the string and decoded it and save it in a variable
    decodedString=`xmlstarlet sel -t -v "/directory-entries/entry/attr/value[@encoding='base64'][$i]" file.xml | tr -d \r\n[:space:] | base64 -d`

    #Now modify the xml document
    xmlstarlet ed -L -u "/directory-entries/entry/attr/value[@encoding='base64'][$i]" -v "$decodedString" file.xml
done

나는 이것을 3 루프 동안 수행했습니다. 원하는 수의 요소로 이 작업을 수행할 수 있습니다.

답변4

xq다음에서 사용https://kislyuk.github.io/yq/:

xq -x '( .. | select(type == "object" and ."@encoding" == "base64")."#text" )
    |= ( gsub("\n"; "") | @base64d )' file.xml

이는 전체 문서를 재귀적으로 탐색하여 encoding값이 base64.인 속성을 가진 노드를 찾습니다. 이러한 각 노드에 대해 노드의 값을 가져오고 모든 줄바꿈을 제거하고( 사용 gsub()) 연산자를 사용하여 base64 문자열을 디코딩합니다 @base64d. 디코딩된 값은 원래 Base64 데이터를 대체합니다.

문제의 문서가 주어지면 출력은 다음과 같습니다.

<directory-entries>
  <entry dn="ads">
    <attr name="memberof">
      <value>CN=VPN-employee</value>
      <value encoding="base64">hello world</value>
      <value encoding="base64">CN=Floppy - доступ закрыт,OU=Device Control,OU=Groups,OU=БАНК,DC=hq,DC=bc</value>
      <value encoding="base64">CN=USB-диски - только чтение,OU=Device Control,OU=Groups,OU=БАНК,DC=hq,DC=bc</value>
    </attr>
  </entry>
</directory-entries>

이 도구 에는 "내부" 편집을 수행 할 수 있는 xq옵션도 있습니다 .-i--in-place

관련 정보