【问题标题】:Powershell script for hash用于哈希的 Powershell 脚本
【发布时间】:2018-04-30 13:40:37
【问题描述】:

我有一个 CSV 文件(逗号分隔值) 该文件如下所示:

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

我需要隐藏(例如)第 3 列中的数据,并且不影响文件中的任何其他条目。

我想使用 SHA1 或 MD5 之类的哈希算法来执行此操作,以便相同的字符串在遇到它们的任何地方都将解析为相同的哈希值。

我需要将数据发送给第三方,并且某些列包含敏感信息(例如客户姓名)。我需要完整的文件,并且在替换字符串的地方,每次遇到它时都需要以相同的方式完成(以便保留任何映射或分组)。它不需要军事加密,只是为了难以逆转。由于我需要间歇性地这样做,因此脚本解决方案将是理想的。

使用命令行工具或脚本实现此目的的最简单方法是什么?

根据偏好,我想要一个 PowerShell 脚本,因为它不需要任何额外的软件来实现...

这个问题似乎与I need to hash (obfuscate) a column of data in a CSV file. Script preferred 重复,但建议的解决方案没有解决我的问题并引发以下错误

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”,因为它为空。

【问题讨论】:

    标签: file powershell csv hash


    【解决方案1】:

    基于the doc,您不会想以这种方式使用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 ','
    

    我相信我基于 this one 的函数,但我已经有一段时间没有编写它了。

    由 LotPings 编辑以显示哈希结果

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

    【讨论】:

    • 非常感谢您的反馈,但这会引发另一个错误 Get-StringHash : Cannot bind argument to parameter 'String' because it is null.
    • @YacineWalid 似乎您正在引用一个不存在的列。您确定您的专栏名称是column3 吗? $csv[0] 显示的列名是什么?
    • @YacineWalid 如果你想要第三列,我会尝试$line.'Column #2'。您使用的列名必须与 CSV 标题中的列名匹配。
    • 是的,它可以工作并且脚本运行正确,但结果 csv 文件中没有发生散列:(
    • 脚本导出到 .\myobfuscated.csv 而不是 results.csv 并且它在这里工作。
    【解决方案2】:

    Bacon Bits 似乎有正确的方法减去一个部分。原始示例中的 ForEach 循环不会修改原始变量。此外,您要修改的列似乎不是“Column3”,而是“Column #2”,因为标题从零开始。我将重复 Bacon Bits 建议中提供的功能。

    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'
    

    【讨论】:

    • 这个解决方案看起来很准确,但对我也不起作用://Select-Object : A parameter cannot be found that match parameter name 'ExcluedeProperty'。
    • 在您的邮件中,您拼写了“排除”错误。如果你拼写正确,那么可能是版本问题?它肯定在第 3 版及更高版本中。
    猜你喜欢
    • 2020-12-04
    • 1970-01-01
    • 2012-10-07
    • 2015-10-25
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多