2020-06-20 08:19:53 -06:00
|
|
|
<# Create SRI hashes for specified files or directory contents #>
|
|
|
|
|
|
|
|
<#
|
|
|
|
.SYNOPSIS
|
|
|
|
Create Sub-Resource Integrity (SRI) SHA hashes for specified files or directory contents.
|
2020-06-20 08:27:12 -06:00
|
|
|
|
2020-06-20 08:19:53 -06:00
|
|
|
.\sri.ps1 -files file1[, file2, ...] -directory /path/to/directory [-filter filter] [-hashAlgo sha256|sha384|sha512]
|
|
|
|
|
|
|
|
.DESCRIPTION
|
2020-06-20 08:27:12 -06:00
|
|
|
Create Sub-Resource Integrity (SRI) SHA-256, SHA-384 or SHA-512 hashes for a specified list of files, a subset of files within a directory, or all files within a directory.
|
2020-06-20 08:19:53 -06:00
|
|
|
|
|
|
|
.PARAMETER files
|
|
|
|
A comma-separated list of files (full path suggested) for which to generate SRI hashes.
|
|
|
|
EXAMPLE: style.css
|
|
|
|
EXAMPLE: /some/path/style.css
|
|
|
|
EXAMPLE: style.css, /some/other/path/menu.css
|
|
|
|
ALIAS: file, list
|
|
|
|
|
|
|
|
.PARAMETER directory
|
|
|
|
Directory containing files for which to generate SRI hashes. Can be filtered using the 'filter' parameter.
|
|
|
|
EXAMPLE: $env:userprofile\myWebSite\css
|
|
|
|
EXAMPLE: C:\Websites\Website1\js
|
|
|
|
|
|
|
|
.PARAMETER filter
|
|
|
|
Process only files matching this criteria. Only relevant for directory operations.
|
|
|
|
DEFAULT: * (all files)
|
|
|
|
EXAMPLE: *.css
|
|
|
|
EXAMPLE: script-site1*.js
|
|
|
|
ALIAS: only, include
|
|
|
|
|
|
|
|
.PARAMETER hashAlgo
|
|
|
|
Use the specified algorithm to generate SRI hashes. Accepts sha256, sha384 (default), sha512.
|
|
|
|
DEFAULT: sha384
|
|
|
|
ALIAS: algorithm
|
|
|
|
|
|
|
|
.EXAMPLE
|
|
|
|
.\sri.ps1 style.css
|
|
|
|
Generate default SHA384 hash for 'style.css' located in the current directory.
|
|
|
|
|
|
|
|
.EXAMPLE
|
|
|
|
.\sri.ps1 style.css, c:\websites\css\menu.css, $env:userprofile\Documents\website\script.js
|
|
|
|
Generate default SHA384 hashes for 'style.css' in the current directory along with the other two files as specified by their full paths.
|
|
|
|
|
|
|
|
.EXAMPLE
|
|
|
|
.\sri.ps1 -directory c:\website\css -hashAlgo sha256
|
|
|
|
Generate SHA256 hashes for all files in the 'C:\Website\css' directory
|
|
|
|
|
|
|
|
.EXAMPLE
|
|
|
|
.\sri.ps1 -dir c:\website\includes -filter *.js -algo sha512
|
|
|
|
Generate SHA512 hashes (partial alias used for '-hashAlgo') for all files matching '*.js' in directory 'C:\website\includes'
|
|
|
|
|
|
|
|
.EXAMPLE
|
|
|
|
.\sri.ps1 -files img\logo.svg, media\video.mp4 -directory css
|
|
|
|
Generate default SHA384 hashes for 'logo.svg' and 'video.mp4' in sub-folders 'img' and 'media', respectively, of the current folder. Then also generate hashes for all files in folder 'css', also a sub-folder of the current folder.
|
|
|
|
#>
|
|
|
|
|
|
|
|
|
2020-06-20 06:00:34 -06:00
|
|
|
param (
|
2020-06-20 07:26:21 -06:00
|
|
|
# List of files to hash
|
|
|
|
[Parameter(HelpMessage="Comma-separated list of files to hash.")]
|
|
|
|
[Alias("file", "list")]
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
[string[]]
|
|
|
|
$files,
|
|
|
|
|
|
|
|
# Directory of files to hash
|
|
|
|
[Parameter(HelpMessage="Hash all files within this directory.")]
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
[string]
|
|
|
|
$directory,
|
|
|
|
|
2020-06-20 08:19:53 -06:00
|
|
|
# File filter to apply to directory operations
|
2020-06-20 07:26:21 -06:00
|
|
|
[Parameter(HelpMessage="Only hash files of this type, relevant only when processing a directory.")]
|
2020-06-20 08:19:53 -06:00
|
|
|
[Alias("only", "include")]
|
2020-06-20 06:00:34 -06:00
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
[string]
|
2020-06-20 07:26:21 -06:00
|
|
|
$filter = '*',
|
2020-06-20 06:00:34 -06:00
|
|
|
|
2020-06-20 07:26:21 -06:00
|
|
|
# Hash algorithm to use
|
|
|
|
[Parameter(HelpMessage="Hash algorithm to use (SHA256, SHA384, SHA512).")]
|
2020-06-20 06:00:34 -06:00
|
|
|
[Alias("algorithm")]
|
|
|
|
[ValidateSet('sha256', 'sha384', 'sha512')]
|
|
|
|
[string]
|
2020-06-20 07:26:21 -06:00
|
|
|
$hashAlgo = 'sha384'
|
2020-06-20 06:00:34 -06:00
|
|
|
)
|
|
|
|
|
2020-06-20 08:19:53 -06:00
|
|
|
|
2020-06-20 07:26:21 -06:00
|
|
|
function displayError($returnCode, $eMsg){
|
|
|
|
Write-Host "`nERROR: $eMsg" -ForegroundColor Red
|
|
|
|
Write-Host "Exiting.`n" -ForegroundColor Red
|
|
|
|
exit $returnCode
|
|
|
|
}
|
|
|
|
|
|
|
|
function hashSHA($type){
|
|
|
|
switch($type){
|
2020-06-20 06:00:34 -06:00
|
|
|
'sha256' { return [System.Security.Cryptography.SHA256]::Create() }
|
|
|
|
'sha384' { return [System.Security.Cryptography.SHA384]::Create() }
|
|
|
|
'sha512' { return [System.Security.Cryptography.SHA512]::Create() }
|
2020-06-20 07:26:21 -06:00
|
|
|
default{
|
|
|
|
displayError 2 'Unknown hash algorithm.'
|
2020-06-20 06:00:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 07:26:21 -06:00
|
|
|
function doHash($file, $hash){
|
2020-06-20 07:43:27 -06:00
|
|
|
try{
|
2020-06-20 07:33:48 -06:00
|
|
|
$fileContents = Get-Content $file -Raw -ErrorAction SilentlyContinue
|
2020-06-20 07:26:21 -06:00
|
|
|
$hashBytes = $hash.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($fileContents))
|
|
|
|
return [System.Convert]::ToBase64String($hashBytes)
|
|
|
|
}
|
2020-06-20 07:43:27 -06:00
|
|
|
catch{
|
2020-06-20 07:26:21 -06:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# instantiate hash provider
|
2020-06-20 06:00:34 -06:00
|
|
|
$hashAlgo = $hashAlgo.ToLower()
|
2020-06-20 07:26:21 -06:00
|
|
|
$hash = hashSHA $hashAlgo
|
2020-06-20 06:00:34 -06:00
|
|
|
|
2020-06-20 07:26:21 -06:00
|
|
|
# process directory, if specified
|
|
|
|
if ($directory){
|
|
|
|
# continue only if directory exists, otherwise exit with error
|
|
|
|
if (Test-Path -Path $directory){
|
2020-06-20 07:43:27 -06:00
|
|
|
Write-Host "Processing directory: $directory" -ForegroundColor Cyan
|
2020-06-20 07:26:21 -06:00
|
|
|
Get-ChildItem -Path $directory -Filter $filter | ForEach-Object({
|
|
|
|
$hashValue = doHash $directory\$_ $hash
|
|
|
|
if ($hashValue -ne 1){
|
|
|
|
Write-Host "$_ --> $hashAlgo-$hashValue" -ForegroundColor Green
|
|
|
|
}
|
2020-06-20 07:43:27 -06:00
|
|
|
else{
|
2020-06-20 07:26:21 -06:00
|
|
|
Write-Host "$_ --> unable to hash file" -ForegroundColor Red
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2020-06-20 07:43:27 -06:00
|
|
|
else{
|
2020-06-20 07:26:21 -06:00
|
|
|
displayError 1 "Directory '$directory' does not exist."
|
|
|
|
}
|
2020-06-20 06:00:34 -06:00
|
|
|
}
|
2020-06-20 07:26:21 -06:00
|
|
|
|
|
|
|
# process file list, if specified
|
|
|
|
if ($files) {
|
2020-06-20 07:43:27 -06:00
|
|
|
Write-Host "Processing files:" -ForegroundColor Cyan
|
2020-06-20 07:26:21 -06:00
|
|
|
foreach ($file in $files) {
|
2020-06-20 07:43:27 -06:00
|
|
|
if (Test-Path -Path $file){
|
|
|
|
$hashValue = doHash $file $hash
|
|
|
|
if ($hashValue -ne 1){
|
|
|
|
Write-Host "$file --> $hashAlgo-$hashValue" -ForegroundColor Green
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Write-Host "$file --> unable to hash file" -ForegroundColor Red
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
Write-Host "$file --> cannot find file" -ForegroundColor Red
|
|
|
|
}
|
2020-06-20 07:26:21 -06:00
|
|
|
}
|
2020-06-20 06:00:34 -06:00
|
|
|
}
|
|
|
|
|
2020-06-20 07:26:21 -06:00
|
|
|
# clean up and exit
|
2020-06-20 07:43:27 -06:00
|
|
|
Write-Host
|
2020-06-20 07:26:21 -06:00
|
|
|
$hash.Dispose()
|
2020-06-20 06:00:34 -06:00
|
|
|
exit 0
|
|
|
|
|
|
|
|
#EOF
|