Скрипт Powershell для хэша - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть файл CSV (значения, разделенные запятыми) Файл выглядит так:

20171108,120909470,SO1244,12,101 
20171109,122715740,AG415757,11,101

Мне нужно скрыть данные в (например) столбцах 3 и, не затрагивая другие записи в файле.

Я хочу сделать это, используя алгоритм хеширования, такой как SHA1 или MD5, чтобы одни и те же строки возвращались к одинаковым значениям хеш-функции везде, где они встречаются.

Мне нужно отправить данные третьему лицу, и некоторые столбцы содержат конфиденциальную информацию (например, имена клиентов). Мне нужно, чтобы файл был завершен, и, когда строка заменяется, мне нужно, чтобы она выполнялась одинаково при каждом обнаружении (чтобы не возникало сопоставления или группировки). Для этого не нужно военное шифрование, просто чтобы его было трудно перевернуть. Поскольку мне нужно к этому периодически, решение на основе сценария было бы идеальным.

Какой самый простой способ добиться этого с помощью инструмента командной строки или сценария?

По желанию я бы хотел сценарий PowerShell, поскольку для этого не требуется никакого дополнительного программного обеспечения ...

Этот вопрос выглядит как дубликат Мне нужно хэшировать (обфусцировать) столбец данных в файле CSV. Сценарий предпочел , но предложенное решение не решило мою проблему и выдает следующую ошибку

You cannot call a method on a null-valued expression.
At C:\Users\mey\Hashr.ps1:4 char:5
+     $_.column3 = $_.column3.gethashcode()

Сценарий следующий

(Import-Csv .\results.csv -delimiter ',' ) | ForEach-Object{ 
 $_.column3 = $_.column3.gethashcode()
 $_
} | Export-Csv .\myobfuscated.csv -NoTypeInformation -delimiter ','

Обновление:

Вот программа, которую я запускаю и которая была предложена @BaconBits:

    param (
    [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
    [String[]]
    $String,
    [Parameter(Position = 1)]
    [ValidateSet('SHA1', 'MD5', 'SHA256', 'SHA384', 'SHA512')]
    [String]
    $HashName = 'SHA256'
)

process {
    $StringBuilder = [System.Text.StringBuilder]::new(128)
    [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String)) | ForEach-Object { 
        [Void]$StringBuilder.Append($_.ToString("x2")) 
    } 
    $StringBuilder.ToString() 
}
}
$csv = Import-Csv .\results.csv -delimiter ',' 
foreach ($line in $csv) {
$line.column1 = Get-StringHash $line.column1
}
$csv | Export-Csv .\myobfuscated.csv -NoTypeInformation -delimiter ','

CSV-файл, который я импортирую, является выводом из другой Java-программы, которую я создал, и он не создает заголовка, он просто заполняет CSV-файл значениями

Я получаю эту ошибку Get-StringHash: невозможно связать аргумент с параметром 'String', поскольку он имеет значение null.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Биты Бекона, кажется, имеют правильную методологию минус одна часть. Цикл ForEach в вашем исходном примере не изменяет исходную переменную. Кроме того, похоже, что столбец, который вы хотите изменить, это не «Column3», а «Column # 2», поскольку заголовки начинаются с нуля. Я повторю функцию, предложенную в предложении Бэкона Бита.

function Get-StringHash { 
    [CmdletBinding()]

    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [String[]]
        $String,
        [Parameter(Position = 1)]
        [ValidateSet('SHA1', 'MD5', 'SHA256', 'SHA384', 'SHA512')]
        [String]
        $HashName = 'SHA256'
    )

    process {
        $StringBuilder = [System.Text.StringBuilder]::new(128)
        [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String)) | ForEach-Object { 
            [Void]$StringBuilder.Append($_.ToString("x2")) 
        } 
        $StringBuilder.ToString() 
    }
}

Я бы предложил заменить:

$csv = Import-Csv .\results.csv | Select-Object *,@{n='Column #2';e={Get-StringHash $_.'Column #2'}} -ExcludeProperty 'Column #2'
$CSV | Export-Csv .\myobfuscated.csv -NoTypeInformation

Это поставит «Столбец № 2» последним в CSV. Вы можете просто перечислить их в явном виде, если вам нужно, чтобы они отображались в том же порядке, например ::

Select-Object 'Column #0','Column #1',@{n='Column #2';e={Get-StringHash $_.'Column #2'}},'Column #3'
0 голосов
/ 30 апреля 2018

Исходя из документа , вы не захотите использовать GetHashCode() таким образом:

Хеш-код предназначен для эффективной вставки и поиска в коллекции, основанные на хеш-таблице. Хеш-код не является постоянное значение. По этой причине:

  • Не сериализуйте значения хеш-кодов и не храните их в базах данных.

  • Не используйте хеш-код в качестве ключа для извлечения объекта из коллекции ключей.

  • Не отправлять хэш-коды через домены приложений или процессы. В некоторых случаях хеш-коды могут быть вычислены для каждого процесса или для каждого домена приложения.

  • Не используйте хеш-код вместо значения, возвращаемого криптографической функцией хеширования, если вам нужен криптографически сильный хэш. Для криптографических хэшей используйте класс, полученный из System.Security.Cryptography.HashAlgorithm или Класс System.Security.Cryptography.KeyedHashAlgorithm.

  • Не проверять на равенство хеш-кодов, чтобы определить, равны ли два объекта. (Неравные объекты могут иметь идентичные хэш-коды.) проверить на равенство, вызвать метод ReferenceEquals или Equals.

Пункт 4 является основной проблемой. Нет гарантии, что хеширование необратимо. Используемая функция хеширования - это деталь реализации, а не безопасная криптографическая функция, такая как SHA.

Я бы использовал такую ​​функцию:

function Get-StringHash { 
    [CmdletBinding()]

    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [String[]]
        $String,
        [Parameter(Position = 1)]
        [ValidateSet('SHA1', 'MD5', 'SHA256', 'SHA384', 'SHA512')]
        [String]
        $HashName = 'SHA256'
    )

    process {
        $StringBuilder = [System.Text.StringBuilder]::new(128)
        [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String)) | ForEach-Object { 
            [Void]$StringBuilder.Append($_.ToString("x2")) 
        } 
        $StringBuilder.ToString() 
    }
}

$csv = Import-Csv .\results.csv -delimiter ',' -Header column1,column2,column3,column4,column5
foreach ($line in $csv) {
    $line.column3 = Get-StringHash $line.column3
}
$csv | Export-Csv .\myobfuscated.csv -NoTypeInformation -delimiter ','

Я полагаю, что основал эту функцию на этой , но прошло некоторое время с тех пор, как я ее написал.

Редактировать с помощью LotPings, чтобы показать результаты хеширования

"column1","column2","column3","column4","column5"
"20171108","120909470","0cdd3c3acdb7cfa107286565c044c5a0f1e58268f6f10e7e3415ff84942e577d","12","101 "
"20171109","122715740","0a7fb9f6bb7a180f2fd9429b0fbd1e7b0a83597b6a64aa6a123cef3e84700fe3","11","101"
...