URL:
Security - Data Transfer with End-To-End Encryption
Requirement
Alice wants to send encrypted Data to Brian.
Brian wants to receive encrypted Data from Alice.
Problem
Digital ID or Secure FTP can't be used, but transfered Data must be protected.
Solution
Encrypt Data with RSA asymmetric algorithm, which use two keys generated by Brian:
🔑︎︎ Private Key - Can be used to decrypt Data, which was encrypted with the Public Key.
🔑︎︎ Public Key - Can be used to encrypt Data. Can NOT be used for decryption.
Steps
- Brian creates 🔑︎︎ Private Key and 🔑︎︎ Public Key.
- Brian sends 🔑︎︎ Public Key to Alice.
- Alice uses 🔑︎︎ Public Key to encrypt Data.
- Alice sends encrypted Data to Brian.
- Brian uses 🔑︎︎ Private Key to decrypt Data.
Step 1: Brian creates Private Key and Public Key.
Step 1a: Generate Private Key and Public Key.
To generate self-signed certificate, which includes matching Private Key and Public Key on computer:
- Press [WINDOWS] + [R] keys to open "Run" window. Type "PowerShell" and press [Enter]:
- PowerShell Window will open. Default location will be set to home folder of the user.
Note: All PowerShell commands will be displayed in dark blue background below.
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\Brian>
- To Generate new self-signed certificate, copy command below, paste into PowerShell Window, and press [Enter] key on keyboard.
New-SelfSignedCertificate `
-DnsName "Brian_DataEncryption" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyUsage KeyEncipherment,DataEncipherment,KeyAgreement `
-Type DocumentEncryptionCert `
-KeyAlgorithm "RSA" `
-KeyLength 4096 `
-HashAlgorithm "SHA256" `
-KeyExportPolicy Exportable
Step 1b: Export 🔑︎ Public Key to file.
Step 1c: Optional Export 🔑︎ Private Key to file.
- Export Private Key by pasting command bellow into PowerShell window and pressing [Enter]
Get-ChildItem `
-DnsName "Brian_DataEncryption" `
-Path "Cert:\CurrentUser\My" `
| Select -Last 1 `
| Export-PfxCertificate `
-Password (ConvertTo-SecureString "password1234" -AsPlainText -Force) `
-FilePath "Brian_DataEncryption.PrivateKey.pfx"
Command to convert Private Key file from binary format to Base64 text format:
CertUtil `
-Encode "Brian_DataEncryption.PrivateKey.pfx" `
"Brian_DataEncryption.PrivateKey.txt"
Command to convert Public Key file from binary format to Base64 text format:
CertUtil `
-Encode "Brian_DataEncryption.PublicKey.cer" `
"Brian_DataEncryption.PublicKey.txt"
Step 2: Brian sends Public Key to Alice.
- Brian must send Brian_DataEncryption.PublicKey.cer file to Alice.
Step 3: Alice uses Public Key to encrypt Data.
Use PowerShell command to generate random password.
Output password as plain text to the screen. Write password to the password.txt file.
Encrypt password as CMS message, which can be decrypted by the holder of Private Key only.
$random = [Byte[]]::new(20); `
$rng = [Security.Cryptography.RNGCryptoServiceProvider]::new(); `
$rng.GetBytes($random); `
$password = [Convert]::ToBase64String($random); `
[IO.File]::WriteAllText("password.txt", $password); `
$password | Protect-CmsMessage `
-To "Brian_DataEncryption.PublicKey.cer" `
-OutFile "password.txt.cms"; `
"`r`nPassword:`r`n"; Get-Content "password.txt"; `
"`r`nEncrypted Password:`r`n"; Get-Content "password.txt.cms"; `
"`r`n";
Convert original file to base64 text format, which is needed for encryption to work properly.
$text = [Convert]::ToBase64String([IO.File]::ReadAllBytes("DataFile.zip"), 1); `
[IO.File]::WriteAllText("DataFile.zip.txt", $text)
Encrypt base64 text file to Cryptographic Message Syntax (CMS) format.
Protect-CmsMessage `
-To "Brian_DataEncryption.PublicKey.cer" `
-Path "DataFile.zip.txt" `
-OutFile "DataFile.zip.txt.cms"
Step 4: Alice sends Encrypted Data to Brian.
Step 5: Brian use Private Key to decrypt Data.
Decrypt Password and display it on the screen
$password = UnProtect-CmsMessage `
-To "CN=Brian_DataEncryption" `
-Path "Password.txt.cms"; `
"`r`nPassword: $password`r`n";
Decrypt CMS file to base64 text format.
UnProtect-CmsMessage `
-To "CN=Brian_DataEncryption" `
-Path "DataFile.zip.txt.cms" `
| Out-File "DataFile.zip.txt" -Encoding ASCII
Convert base64 text file to original file.
$bytes = [Convert]::FromBase64String([IO.File]::ReadAllText("DataFile.zip.txt")); `
[IO.File]::WriteAllBytes("DataFile.zip", $bytes)