PowerShell Return True or False for Certificates

email me

This is something I created to return a True or False whether or not specified computer certificates are installed. It writes this information to the registry for desktop management software scanning. My original objective was just to determine whether or not an old (about to expire) cert still existed, but I went ahead and added detection for the new one as well.

# AUTHOR: Eddie Jackson
# DATE: 03/28/2017
# USAGE: To verify if specified certs are in local
# store
# NOTES: Desktop Management will report on reg keys
# set to TRUE or FALSE

Clear-Host

# OLD Cert Thumbprint
$Cert1 = "12345678912C7409FBF28C86D208637123456789"

# New Cert Thumbprint
$Cert2 = "FD5C3FC1F3C405D1D468EF0A0A12345678912345"

# Reg Path
$RegPath = 'HKLM:\SOFTWARE\COMPANY\AppName\Cert'

# Clear Session
$OLD = ""
$NEW = ""
Remove-ItemProperty -Path $RegPath -Name "$Cert1" | Out-Null
Remove-ItemProperty -Path $RegPath -Name "$Cert2" | Out-Null
New-Item -Path $RegPath -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "$Cert1" -Value "FALSE"
New-ItemProperty -Path $RegPath -Name "$Cert2" -Value "FALSE"
Start-Sleep 5 # time to verify reg keys are reset

# Assign Current Certs to variables
$OLD = Get-ChildItem Cert:\LocalMachine\My | Select -Property Thumbprint |
Where-Object {$_.Thumbprint -eq "$Cert1"} |
foreach { $_.Thumbprint }

$NEW = Get-ChildItem Cert:\LocalMachine\My | Select -Property Thumbprint |
Where-Object {$_.Thumbprint -eq "$Cert2"} |
foreach { $_.Thumbprint }

# Determine if Certs exist
if ($OLD -eq "$Cert1") {
#Write-Host "Old Exists"
New-ItemProperty -Path $RegPath -Name "$Cert1" -Value "TRUE" -Force | Out-Null

}

if ($NEW -eq "$Cert2") {
#Write-Host "New Exists"
New-ItemProperty -Path $RegPath -Name "$Cert2" -Value "TRUE" -Force | Out-Null
}

 
Screenshot of registry

Enable/Disable SMBv1, SMBv2, SMBv3

email me

Microsoft has released a security update to address a vulnerability in implementations of Server Message Block 1.0 (SMBv1). Exploitation of this vulnerability could allow a remote attacker to take control of an affected system.

US-CERT encourages users and administrators to review Microsoft Security Bulletin MS17-010 and apply the update. For more information, see the Information Assurance Advisory and US-CERT’s SMB Security Best Practices guidance.

Note, ever since Windows 10 Build 1709, the reg keys don’t work so great (that’s because MS has removed the SMBv1 feature, altogether). Use dism or PowerShell cmdlets instead.

 

Return all protocols

dism /online /get-features /format:table


Enable SMBv1 via PowerShell

Enable-WindowsOptionalFeature -Online -FeatureName smb1protocol -norestart


Enable SMBv1 via Dism

dism /online /enable-feature /featurename:SMB1Protocol-Server -NoRestart

To check the status of SMB versions on your servers (from PowerShell)

Get-SMBServerConfiguration

Snapshot 

 

This is the reg key for SMBv1:

Steps to enable and disable the SMBv1 on the SMB server using the registry:

Registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Registry entry: SMB1
REG_DWORD: 0 = Disabled
REG_DWORD: 1 = Enabled
Default: 1 = Enabled

For SMBv2…

Registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Registry entry: SMB2
REG_DWORD: 0 = Disabled
REG_DWORD: 1 = Enabled
Default: 1 = Enabled

 

Notes

https://technet.microsoft.com/en-us/library/security/mt745122.aspx

https://support.microsoft.com/en-gb/help/2696547/how-to-enable-and-disable-smbv1,-smbv2,-and-smbv3-in-windows-vista,-windows-server-2008,-windows-7,-windows-server-2008-r2,-windows-8,-and-windows-server-2012

Other Bulletins (yes, you should be reading these)
https://technet.microsoft.com/en-us/library/security/mt745122.aspx

 

Commands

Disables the SMBv1 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi
sc.exe config mrxsmb10 start= disabled

Enables the SMBv1 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb10 start= auto

Disables the SMBv2 and SMBv3 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/nsi
sc.exe config mrxsmb20 start= disabled

Enables the SMBv2 and SMBv3 on the SMB client by running the below commands
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb20 start= auto

 

Script to Disable SMB

@echo off
Title Manage SMB
cls

:DISABLE
%windir%\system32\sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi >log.txt
%windir%\system32\sc.exe config mrxsmb10 start= disabled >>log.txt

%windir%\system32\sc.exe config lanmanworkstation depend= bowser/mrxsmb10/nsi >>log.txt
%windir%\system32\sc.exe config mrxsmb20 start= disabled >>log.txt

%windir%\system32\EVENTCREATE.exe /T INFORMATION  /l Application  /ID 777 /d “Disabled SMB”
exit

 

 

PowerShell

Disables the SMBv1 on the SMB server by running the below command

Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB1 -Value 0 –Force


Disables the SMBv2 and SMBv3 on the SMB server by running the below command

Set-ItemProperty –Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB2 –Value 0 –Force


Enables the SMBv1 on the SMB server by running the below command

Set-ItemProperty –Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB1 –Value 1 –Force

Enables the SMBv2 and SMBv3 on the SMB server by running the below command

Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” SMB2 -Value 1 -Force

SCCM Change Site Code

email me

This is a quick way to update a client’s site code. Make sure you run as admin.

I ended up needing this, because while our SCCM was being configured at the forest level (which took a while), I was already testing the SCCM server. Without this, the clients could not communicate with the server.

Set objShell = CreateObject("WScript.Shell")
set objSMSClient = CreateObject ("Microsoft.SMS.Client")

'update site code
objSMSClient.SetAssignedSite "ABC",0

'restart process
objShell.Run "C:\Windows\CCM\CcmRestart.exe",0,true

msgbox " Site code has been changed!"

PowerShell – Return Computer name, Count of Missing Updates, Missing KBs

email me

This will return missing patches (missing security and critical updates) based upon a KB text file. I used a fully patched computer + the published KBs from a patch server to create a master KBs.txt file. The KB file contains KBs by the numbers: KB11111, KB22222, etc (one per line). I also have a computers.txt file which permits you to query missing updates on multiple computers, remotely. Just to verify it was at least hitting the right ballpark number, I installed Belarc to crosscheck missing updates. So far, it has been 100% accurate.

The data comes out in CSV format (click image to zoom)

 

What you need

  • KBs.txt
  • Computers.txt
  • Admin access
  • The script I created below

 

Clear-Host

# Path to files
$filePath = "C:\scripts"

# the computers to check
$computerList = Get-Content -Path "$filePath\computers.txt" 

# the KBs to check
$patchList = Get-Content -Path "$filePath\KBs.txt" 

$E_Total = "" # exists total
$NE_Total = "" # not exists total
$Count = 0 # missing updates counter
$BoolCheck = 0 

 
foreach ($computer in $computerList)
{  
    
    # is machine online?
    $Ping = test-connection -ComputerName $computer -Count 2 -quiet 
 
    # yes, online
     if($Ping) 
        {         
       
        # get current list of hotfixes on machine
        $HotfixList = Get-HotFix -ComputerName $computer | select -Property "HotFixID"
 
        # cycle through each patch in list
        foreach($patch in $patchList)
        {         
            $BoolCheck=0
            
            
            # cycle through hotfixes on local machine
            foreach ($Hotfix in $HotfixList)                
            { 

                # compare local machine hotfixes with our list
                # if it matches, exists
                if ($patch -eq $Hotfix.HotFixID) 
                    {       
                        $BoolCheck=1                          
                        break
                      }             
                      
                       
                  }
               
               if ($found -eq 1) {
               $E_Total = "$E_Total,$patch"
               }
               
               if ($BoolCheck -eq 0) {
               # $patch
               $NE_Total = "$NE_Total,$patch"
               $Count=$Count+1
               }                
                   
            }
            # Write-Host "Found:   $Computer$E_Total"            
            Write-Host "$Computer,Missing $count$NE_Total"
            Write-Host " "
            
            # Clear session
            $E_Total = ""
            $NE_Total = ""
            $Count = 0
            $BoolCheck = 0
            
            
}
 
# no, not online
else 
{ 
Write-Host "$Computer,Not Online"
Write-Host " "
} 
}

 

The KBs in the KBs.txt file I used…though, yours will most likely be different due to imaging practices and new KB releases.

KB2305420
KB2393802
KB2479943
KB2491683
KB2506014
KB2506212
KB2506928
KB2509553
KB2511455
KB2515325
KB2533552
KB2536275
KB2536276
KB2538242
KB2544893
KB2545698
KB2547666
KB2552343
KB2560656
KB2563227
KB2564958
KB2565063
KB2570947
KB2574819
KB2579686
KB2584146
KB2585542
KB2592687
KB2603229
KB2604115
KB2619339
KB2620704
KB2621440
KB2631813
KB2640148
KB2644615
KB2647753
KB2654428
KB2660075
KB2661254
KB2667402
KB2670838
KB2676562
KB2685811
KB2685813
KB2685939
KB2690533
KB2698365
KB2705219
KB2709630
KB2709981
KB2712808
KB2718704
KB2719857
KB2726535
KB2727528
KB2729094
KB2732059
KB2732487
KB2732500
KB2736422
KB2742599
KB2750841
KB2761217
KB2763523
KB2770660
KB2773072
KB2786081
KB2791765
KB2799926
KB2803821
KB2807986
KB2808679
KB2813170
KB2813347
KB2813430
KB2820331
KB2832414
KB2834140
KB2835361
KB2839894
KB2840631
KB2841134
KB2843630
KB2846960
KB2847077
KB2847311
KB2847927
KB2849696
KB2849697
KB2852386
KB2853952
KB2861191
KB2861698
KB2861855
KB2862152
KB2862330
KB2862335
KB2862966
KB2862973
KB2864058
KB2864202
KB2868038
KB2868116
KB2868626
KB2872339
KB2884256
KB2887069
KB2888049
KB2891804
KB2892074
KB2893294
KB2893519
KB2900986
KB2910978
KB2911501
KB2912390
KB2913152
KB2913431
KB2918077
KB2919469
KB2920680
KB2929733
KB2929755
KB3072305
KB3085538
KB3085635
KB3087038
KB3101512
KB3114518
KB3115041
KB3115103
KB3115135
KB3115858
KB3122648
KB3124280
KB3126446
KB3127220
KB3127986
KB3178656
KB3178673
KB3178674
KB3210131
KB4012204
KB4012212
KB4013867
KB954430
KB958488
KB971033
KB976902
KB976932
KB982018

Dimming and Lighting Through Opacity

email me

This is a simple way to control the opacity and color of objects and elements on a web form.

<script type="text/javascript">
function HideBox() {
	document.body.style.filter = "alpha(opacity=35)";
	document.body.style.backgroundColor = "#002e4d";
}

function ShowBox() {
	document.body.style.filter = "alpha(opacity=100)";
	document.body.style.backgroundColor = "#99ccff";
}
</script>

 

Notes

I used this in an HTA to dim the form when a dialog box appears.

Screenshot

 

A C# method, taken from a forum

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace WindowsApplication1 { 
  public partial class FMask : Form { 
    public FMask(Form parent) { 
      InitializeComponent(); 
      this.FormBorderStyle = FormBorderStyle.None; 
      this.BackColor = Color.Black; 
      this.Opacity = 0.50; 
      this.ShowInTaskbar = false; 
      this.StartPosition = FormStartPosition.Manual; 
      this.Size = parent.ClientSize; 
      this.Location = parent.PointToScreen(Point.Empty); 
      parent.Move += AdjustPosition; 
      parent.SizeChanged += AdjustPosition; 
    } 
    private void AdjustPosition(object sender, EventArgs e) { 
      Form parent = sender as Form; 
      this.Location = parent.PointToScreen(Point.Empty); 
      this.ClientSize = parent.ClientSize; 
    } 
  } 
} 

Then in your original Form1, remove the TransPanel code and add a Load event:

    private FMask overlay; 
    private void Form1_Load(object sender, EventArgs e) { 
      overlay = new FMask(this); 
      overlay.Show(this); 
    } 

To remove the overlay, just call overlay.Close() and set overlay = null.

 

From MSDN

private void Form1_Load_1(object sender, EventArgs e) 
    { 
        panel1.BackColor = Color.FromArgb(128, 0, 0, 0); 
    } 

More…

Shockwave GUIDs

email me

Perhaps this could be of some use to someone out there

11.6.5.636
msiexec.exe /X{459F2CFC-D6E0-48EA-BF86-C6C9EE5F405F} /qn /norestart

11.6.7.637
msiexec.exe /X{05217ED3-D9CA-4302-BCEF-4753596181B8} /qn /norestart

11.6.8.638
msiexec.exe /X{9B92B20A-6A19-428F-8BD0-52DF859B1C61} /qn /norestart

12.0.3.133
msiexec.exe /X{0099B484-C24C-4D5F-8167-B0F6DF196E72} /qn /norestart

12.0.4.144
msiexec.exe /X{BCFB58FF-181E-472F-A9DB-827B75C1EDF7} /qn /norestart

12.0.5.146
msiexec.exe /X{612C34C7-5E90-47D8-9B5C-0F717DD82726} /qn /norestart

12.0.6.147
msiexec.exe /X{9A3AB849-5758-4C2D-88FD-92FC880AE9F6} /qn /norestart

12.0.7.148
msiexec.exe /X{AA3B06B1-E89A-43C6-A26B-7109DB4BEE7B} /qn /norestart

12.0.5.155
msiexec.exe /X{A04CB48B-B82B-406B-ABAA-209F098F03A4} /qn /norestart

12.2.5.195
msiexec.exe /X{A2116AF9-FA9D-41EA-9874-1E40B227D4DE} /qn /norestart

12.2.5.196
msiexec.exe /X{A2116AF9-FA9D-41EA-9874-1E40B227D4DE} /qn /norestart

12.2.7.197
msiexec.exe /X{2595E6DD-D6D4-42FC-80A8-6A711EBEC344} /qn /norestart

12.2.8.198
msiexec.exe /X{52B66F1A-E977-41EE-8359-3C4040BE72F5} /qn /norestart

C# – Change Admin Password and Add Encrypted Reg Key

email me

Just a few things to note:

— Always store your source code in a secure location.

— If you want to use the encrypted pw in the registry,
I recommend naming the reg key itself to something
obscure (not AdminPassword).

— Don’t forget to change the permutations for every
new password.

— And, only pass the encrypted password between your
compiled apps. Code the application to decrypt the
password.

— I have added all the methods together here—for demo purposes—you want to
separate the encrypt and decrypt into two EXEs.

Screenshot of an encrypted reg key

 

using System;
using System.IO;                    // MemoryStream
using System.Security.Cryptography; // used by aes
using System.Text;                  // used by Encoding
using Microsoft.Win32;              // used by Registry
using System.Windows.Forms;         // used by Messagebox
using System.Diagnostics;           // used by Process

namespace SecurePassword
{
    class ResetPassword
    {       

        public static class Global
        {
            // Set password
            public const string strPassword = "LetMeIn99$";

            // Testing
            //public const String strPassword = "ABCZYZabczyx123890!@\"\\#/:;<>?$%^&*()-_+={}[]";

            // set permutations
            public const string strPermutation = "ouiveyxaqtd";
            public const int bytePermutation1 = 0x19;
            public const int bytePermutation2 = 0x59;
            public const int bytePermutation3 = 0x17;
            public const int bytePermutation4 = 0x41;

            // set reg value
            public const string strRegHive = "HKEY_LOCAL_MACHINE";
            public const string strRegKey = @"SOFTWARE\ZWTValue\";
            public const string strRegPath = strRegHive + @"\" + strRegKey;
            public const string strRegVal = "ZWTValue1";          

        }




        public static void Main(string[] args)
        {
            {

    // BEGIN - ENCRYPT PASSWORD
            
                // encrypt
                string strEncrypted = (Encrypt(Global.strPassword));
    
    // END - ENCRYPT PASSWORD




    // BEGIN - ADD ENCRYPTED PASSWORD TO REGISTRY 

                // try set reg value
                try
                {
                    //requires admin access
                    Registry.SetValue(Global.strRegPath, Global.strRegVal, strEncrypted, RegistryValueKind.String);
                    // reference https://msdn.microsoft.com/en-us/library/3dwk5axy(v=vs.110).aspx                

                }

                // catch if there is an error in encrypt
                // ex.Exception
                catch (Exception)
                {
                    //MessageBox.Show(ex.ToString());
                }
    // END - ADD ENCRYPTED PASSWORD TO REGISTRY




    // BEGIN - CHANGE PASSWORD

                // try to change password
                // set properties for process                       
                // requires admin access
                ProcessStartInfo cmdProcess = new ProcessStartInfo("net.exe", "user administrator \"" + Global.strPassword + "\"");
                cmdProcess.RedirectStandardOutput = false;
                cmdProcess.WindowStyle = ProcessWindowStyle.Hidden; // hide window
                cmdProcess.UseShellExecute = true;
                Process checkProcess = null;

                try
                {
                    // launch command
                    checkProcess = Process.Start(cmdProcess);
                    checkProcess.WaitForExit();
                    // reference https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx

                    ////MessageBox.Show(checkProcess.ExitCode.ToString());                   

                    if (checkProcess.ExitCode == 0)
                    {

                        // MessageBox.Show("  Local admin password was reset!");
                        // reference https://msdn.microsoft.com/en-us/library/system.environment.exitcode(v=vs.110).aspx
                    }
                }


                catch (Exception)
                // ex.Exception
                {
                    // MessageBox.Show(ex.ToString());
                }

    // END - CHANGE PASSWORD




    // BEGIN - READ PASSWORD FROM REGISTRY

                string strRegTest = "false";

                // sets the encrypted pw value, to What the reg value should be
                string strEncryptedRegValue = strEncrypted;                

                // try opening reg key
                try
                    {
                        // return encrypted key from registry
                        RegistryKey returnKey = Registry.LocalMachine.OpenSubKey(Global.strRegKey);

                        string rkValue = returnKey.GetValue(Global.strRegVal).ToString();
                        //reference https://msdn.microsoft.com/en-us/library/z9f66s0a(v=vs.110).aspx
                        returnKey.Close();

                    if (returnKey != null)
                            
                         // try testing encrypted key with encrypted pw value
                         try
                               {
                                    if (strEncrypted == rkValue)
                                {
                                    //MessageBox.Show("True");
                                    strRegTest = "true";
                                }

                                    else

                                 {
                                //MessageBox.Show("False");
                                strRegTest = "false";
                                }
                            }
                        // will catch errors reading values
                        catch (Exception)
                        {

                        }                   

                }
                // will catch reg error where no key exists
                catch (Exception)
                {
                    //MessageBox.Show("There is no value!");
                    strRegTest = "false";
                }

                 // decrypt
                 //string strDecrypted = (Decrypt(strEncrypted));
                 string strDecrypted = (Decrypt(rkValue.ToString()));
                 //MessageBox.Show(strDecrypted);

    // END - READ PASSWORD FROM REGISTRY




    // BEGIN OUTPUT
                                
                MessageBox.Show("Original: " + Global.strPassword + "\n\n" + 
                               "Encrypted: " + strEncrypted + "\n\n" + 
                               "Decrypted: " + strDecrypted + "\n\n" + 
                               "Reg Test (is key the same?): " + strRegTest);
    // END OUTPUT
               
                
            }
                    
        }
        
        
        
        
        // encoding
        public static string Encrypt(string strData)
        {
            return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(strData)));
            // reference https://msdn.microsoft.com/en-us/library/ds4kkd55(v=vs.110).aspx

        }


        // decoding
        public static string Decrypt(string strData)
        {
            return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(strData)));
            // reference https://msdn.microsoft.com/en-us/library/system.convert.frombase64string(v=vs.110).aspx

        }

        // encrypt
        public static byte[] Encrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize/8);
            aes.IV = passbytes.GetBytes(aes.BlockSize/8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateEncryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }

        // decrypt
        public static byte[] Decrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize/8);
            aes.IV = passbytes.GetBytes(aes.BlockSize/8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateDecryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }
        // reference 
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
    }
}

C# – Change Local Admin Password

email me

try
{
// change password
System.Diagnostics.Process.Start("net.exe", "user administrator " + "NewPasswordHere");
}
catch (Exception)
{
}

 

Notes

String 0ADSPath = “LDAP://onecity/CN=Users,
DC=onecity,DC=corp,DC=fabrikam,DC=com”;

DirectoryEntry oDirectoryEntry = new DirectoryEntry(oADSPath);
oDirectoryEntry.Username = UserName;
oDirectoryEntry.Password = SecureStringStoredPassword;

C# – Encrypt/Decrypt Password

email me

I wrote this in C# to encrypt and decrypt a password, which could be stored in a file, or perhaps the registry. It converts the password into a byte string, that byte string is converted using base64, and then is encrypted using AES. Take note, I have added permutations for the byte streams. These should be changed for every password you encrypt. One final thought, the overall security of this process depends on the protection of your C# code. So…compile this, and keep any source code in a secure location. This is not meant to be used as a secure app for distribution, just as a method to generate the encrypted password. If you’re trying to create a standalone app, look into AppendChar.

Screenshot

 

Code

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SecurePassword
{
    class Encode_Decode
    {
        public static class Global
        {
            // set password
            public const string strPassword = "LetMeIn99$";

            // set permutations
            public const String strPermutation = "ouiveyxaqtd";
            public const Int32 bytePermutation1 = 0x19;
            public const Int32 bytePermutation2 = 0x59;
            public const Int32 bytePermutation3 = 0x17;
            public const Int32 bytePermutation4 = 0x41;         
        }


        // The console window
        public static void Main(String[] args)
        {           
            
            Console.Title = "Secure Password v2";
            Console.WriteLine("Output---");
            Console.WriteLine("");
            
            Console.WriteLine("Password:  " + Global.strPassword);

            string strEncrypted = (Encrypt(Global.strPassword));
            Console.WriteLine("Encrypted: " + strEncrypted);

            string strDecrypted = (Decrypt(strEncrypted));
            Console.WriteLine("Decrypted: " + strDecrypted);

            Console.ReadKey();
        }

 


        // encoding
        public static string Encrypt(string strData)
        {

            return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(strData)));
            // reference https://msdn.microsoft.com/en-us/library/ds4kkd55(v=vs.110).aspx

        }


        // decoding
        public static string Decrypt(string strData)
        {
            return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(strData)));
            // reference https://msdn.microsoft.com/en-us/library/system.convert.frombase64string(v=vs.110).aspx

        }

        // encrypt
        public static byte[] Encrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize/8);
            aes.IV = passbytes.GetBytes(aes.BlockSize/8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateEncryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }

        // decrypt
        public static byte[] Decrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize/8);
            aes.IV = passbytes.GetBytes(aes.BlockSize/8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateDecryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }
        // reference
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography(v=vs.110).aspx
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
        // https://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
    }
}

C# – Hashes and Comparisons

email me

This is hashing I’ve done in C#. I have included MD5, SHA1, SHA256, SHA384, and SHA512, the hashes, and then validation of a working versus non-working password.

Screenshot

The code…just copy/paste into Visual Studio Console Project and compile.

using System;
using System.Text;
using System.Security.Cryptography;

public class ReturnHash
{
    public static string ComputeHash(string plainText, string hashAlgorithm, byte[] saltBytes)
    {
        // Salt size
        saltBytes = new byte[8];

        // Convert Text to Array
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        // Create Array
        byte[] plainTextSaltBytes =
                new byte[plainTextBytes.Length + saltBytes.Length];

        // Copy Text into Array
        for (int i = 0; i < plainTextBytes.Length; i++)
            plainTextSaltBytes[i] = plainTextBytes[i];

        // Append Salt
        for (int i = 0; i < saltBytes.Length; i++)
            plainTextSaltBytes[plainTextBytes.Length + i] = saltBytes[i];

        // Algorithm
        HashAlgorithm hash;

        // Initialize Class
        switch (hashAlgorithm.ToUpper())
        {
            case "SHA1":
                hash = new SHA1Managed();
                break;

            case "SHA256":
                hash = new SHA256Managed();
                break;

            case "SHA384":
                hash = new SHA384Managed();
                break;

            case "SHA512":
                hash = new SHA512Managed();
                break;

            default:
                hash = new MD5CryptoServiceProvider();
                break;
        }

        byte[] hashBytes = hash.ComputeHash(plainTextSaltBytes);

        byte[] hashSaltBytes = new byte[hashBytes.Length +
                                            saltBytes.Length];

        // Hash to Array
        for (int i = 0; i < hashBytes.Length; i++)
            hashSaltBytes[i] = hashBytes[i];

        // Append Salt
        for (int i = 0; i < saltBytes.Length; i++)
            hashSaltBytes[hashBytes.Length + i] = saltBytes[i];

        // Convert result into a base64-encoded string.
        string hashValue = Convert.ToBase64String(hashSaltBytes);

        // Return Result
        return hashValue;
    }

    public static bool VerifyHash(string plainText,
                                  string hashAlgorithm,
                                  string hashValue)
    {
        // Base64-encoded hash
        byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue);

        // Hash without Salt
        int hashSizeInBits, hashSizeInBytes;

        // Size of hash is based on the specified algorithm.
        switch (hashAlgorithm.ToUpper())
        {
            case "SHA1":
                hashSizeInBits = 160;
                break;

            case "SHA256":
                hashSizeInBits = 256;
                break;

            case "SHA384":
                hashSizeInBits = 384;
                break;

            case "SHA512":
                hashSizeInBits = 512;
                break;

            default: // MD5
                hashSizeInBits = 128;
                break;
        }

        // Convert to bytes.
        hashSizeInBytes = hashSizeInBits / 8;

        // Verify Hash Length
        if (hashWithSaltBytes.Length < hashSizeInBytes)
            return false;

        // Array to hold Salt
        byte[] saltBytes = new byte[hashWithSaltBytes.Length -
                                    hashSizeInBytes];

        // Salt to New Array
        for (int i = 0; i < saltBytes.Length; i++)
            saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];

        string expectedHashString =
                    ComputeHash(plainText, hashAlgorithm, saltBytes);

        return (hashValue == expectedHashString);
    }
}

public class PasswordEncodingTest1
{
    [STAThread]
    static void Main(string[] args)
    {
        // Test Passwords
        string rightPassword = "TRUEPassword$";
        string wrongPassword = "FALSEPassword$";

        string passwordHashMD5 =
               ReturnHash.ComputeHash(rightPassword, "MD5", null);
        string passwordHashSha1 =
               ReturnHash.ComputeHash(rightPassword, "SHA1", null);
        string passwordHashSha256 =
               ReturnHash.ComputeHash(rightPassword, "SHA256", null);
        string passwordHashSha384 =
               ReturnHash.ComputeHash(rightPassword, "SHA384", null);
        string passwordHashSha512 =
               ReturnHash.ComputeHash(rightPassword, "SHA512", null);

        
        Console.WriteLine("Hash and Comparison--- \r\n");

        // md5
        Console.WriteLine("MD5 {0}", passwordHashMD5);
            Console.WriteLine("Right PW MD5     {0}",
            ReturnHash.VerifyHash(
            rightPassword, "MD5",
            passwordHashMD5).ToString());
            Console.WriteLine("Wrong PW MD5     {0}",
            ReturnHash.VerifyHash(
            wrongPassword, "MD5",
            passwordHashMD5).ToString());
            Console.WriteLine("");
            // reference https://en.wikipedia.org/wiki/MD5
            // https://msdn.microsoft.com/en-us/library/system.security.cryptography.md5(v=vs.110).aspx

        // sha1
        Console.WriteLine("SHA1 {0}", passwordHashSha1);
            Console.WriteLine("Right PW SHA1    {0}",
            ReturnHash.VerifyHash(
            rightPassword, "SHA1",
            passwordHashSha1).ToString());
            Console.WriteLine("Wrong PW SHA1    {0}",
            ReturnHash.VerifyHash(
            wrongPassword, "SHA1",
            passwordHashSha1).ToString());
            Console.WriteLine("");
            // reference https://en.wikipedia.org/wiki/SHA-1
            // https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1(v=vs.110).aspx

        // sha256
        Console.WriteLine("SHA256 {0}", passwordHashSha256);
            Console.WriteLine("Right PW SHA256  {0}",
            ReturnHash.VerifyHash(
            rightPassword, "SHA256",
            passwordHashSha256).ToString());
            Console.WriteLine("Wrong PW SHA256  {0}",
            ReturnHash.VerifyHash(
            wrongPassword, "SHA256",
            passwordHashSha256).ToString());
            Console.WriteLine("");
            // reference https://en.wikipedia.org/wiki/SHA-2
            // https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256(v=vs.110).aspx

        // sha384
        Console.WriteLine("SHA384 {0}", passwordHashSha384);
            Console.WriteLine("Right PW SHA384  {0}",
            ReturnHash.VerifyHash(
            rightPassword, "SHA384",
            passwordHashSha384).ToString());
            Console.WriteLine("Wrong PW SHA384  {0}",
            ReturnHash.VerifyHash(
            wrongPassword, "SHA384",
            passwordHashSha384).ToString());
            Console.WriteLine("");
            // reference https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha384(v=vs.110).aspx

        // sha512
        Console.WriteLine("SHA512 {0}", passwordHashSha512);
            Console.WriteLine("Right PW SHA512  {0}",
            ReturnHash.VerifyHash(
            rightPassword, "SHA512",
            passwordHashSha512).ToString());
            Console.WriteLine("Wrong PW SHA512  {0}",
            ReturnHash.VerifyHash(
            wrongPassword, "SHA512",
            passwordHashSha512).ToString());
            // reference https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha512(v=vs.110).aspx

        Console.WriteLine("");
        Console.WriteLine("");


        Console.ReadKey();
    }
}

Encoding and Decoding a Stored Password: v1

email me

I created this to store passwords in a more secure manner. It could be used to encode a password, and also to retrieve and decode a password. I do permutations based upon a specified number to perform the shift in ASCII (polyalphabetic substitution cipher), but…I’d also like to add a more advanced method, which would increase the complexity of encoding using multiple formulas based upon positioning. As this will be considered v1, I’ll post v2 when complete.

Screenshots

Option Explicit

Dim ASCII_Code1, returnASCII, returnCharacterPermutation, concatenateASCIIPermutation
Dim addPermutation, concatenateASCII, concatenatePermutation, password, iStep, Permutation1
Dim reversePermutation, returnCharacterPermutation2, concatenateASCIIPermutation2, returnLength
Dim concatenateASCII2, ASCII_Registry, Permutation2, concatenatePermutation2, PasswordLength, PermutationConstant


''''''''''''''''''''''''''''''''''''''''''''''''''''''
'PASSWORD TO ENCODE
password = "ABC-XYZ-abc-xyz-0987654321-""-!@#$%^&*(){}|\|/?<>,._-+=`~"
'password = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrstuvwxyz-0987654321-""-!@#$%^&*(){}|\|/?<>,._-+=`~"

'PERMUTATION CAN BE CHANGED 1-55
Permutation1 = 3

''''''''''''''''''''''''''''''''''''''''''''''''''''''




'SESSION
PasswordLength = 0
iStep = 0
concatenateASCII = ""
concatenatePermutation = ""
ASCII_Code1 = ""
ASCII_Registry = ""

PermutationConstant = Permutation1


'ENCODES PASSWORD

FOR iStep = 1 TO LEN(password)
   ASCII_Code1 = Asc(MID(password,iStep,1))
   'num conversion
   ASCII_Code1 = CINT(ASCII_Code1)
   
   concatenateASCII = ASCII_Code1 & " " & concatenateASCII     
   
   'ADD PERMUTATION
   addPermutation = ASCII_Code1 + Permutation1
   returnCharacterPermutation = chr(addPermutation)
   concatenateASCIIPermutation = returnCharacterPermutation + concatenateASCIIPermutation   
   concatenatePermutation = addPermutation & " " & concatenatePermutation
    
   Permutation1 = Permutation1 + 1
NEXT




'DECODES PASSWORD - WILL COME FROM REGISTRY
'concatenateASCIIPermutation = regvalue, eventually

'return length of password
PasswordLength = LEN(concatenateASCIIPermutation)
'the permutation numeric is created subtracting 1 from original number 
'and adding the total length of the encoded password
Permutation2 = (PermutationConstant - 1) + PasswordLength

iStep = 0
FOR iStep = 1 TO LEN(concatenateASCIIPermutation)
   ASCII_Registry = Asc(MID(concatenateASCIIPermutation,iStep,1))
   'num conversion
   ASCII_Registry = CINT(ASCII_Registry)
   
   concatenateASCII2 = ASCII_Registry & " " & concatenateASCII2
   
   'REVERSE PERMUTATION   
   reversePermutation = ASCII_Registry - Permutation2 
   returnCharacterPermutation2 = chr(reversePermutation)
   concatenateASCIIPermutation2 = returnCharacterPermutation2 + concatenateASCIIPermutation2   
   concatenatePermutation2 = reversePermutation & " " & concatenatePermutation2   
   
   Permutation2 = Permutation2 - 1
NEXT
   

   
'OUTPUT
MSGBOX "[Password]" & chr(10) & password & chr(10) & chr(10) & _
	   "[ASCII Code]" & chr(10) & concatenateASCII & chr(10) & chr(10) & _
	   "[Add Permutation]" & chr(10) & concatenatePermutation & chr(10) & chr(10) & _	   
	   "[Encoded Password]" & chr(10) & concatenateASCIIPermutation & chr(10) & chr(10) & _
	   "[Registry ASCII Code]" & chr(10) & concatenateASCII2 & chr(10) & chr(10) & _
	   "[Reverse Permutation]" & chr(10) & concatenatePermutation2,64,"Decode"
	   
MSGBOX "[Password]" & chr(10) & password & chr(10) & chr(10) & _
       "[Encoded Password]" & chr(10) & concatenateASCIIPermutation & chr(10) & chr(10) & _
	   "[Decoded Password]" & chr(10) & concatenateASCIIPermutation2,64,"Decode"
	   


ASCII_Code1 = ""
returnASCII = ""
returnCharacterPermutation = ""
concatenateASCIIPermutation = ""
addPermutation = ""
concatenateASCII = ""
concatenatePermutation = ""
password = ""
iStep = ""
Permutation1 = ""
reversePermutation = ""
returnCharacterPermutation2 = ""
concatenateASCIIPermutation2 = ""
returnLength = ""
concatenateASCII2 = ""
ASCII_Registry = ""
Permutation2 = ""
concatenatePermutation2 = ""
PasswordLength = ""
PermutationConstant = ""
   
WScript.Quit(0)

 

Notes

In v2 (to provide better security for passwords, specifically), what I’m going to do is create unique formulas for each position. It may be written in VB or C#.

So, a potential password, let’s say LetMeIn99$, could look like this once encoded: AAAAAAAAAA.

The idea is that there is zero correlation between one position, to the next, as seen from the onlooker.

 

From Bruce Schneier’s Applied Cryptography, 2nd edition…

Substitution Ciphers

A substitution cipher is one in which each character in the plaintext is substituted for another character in the ciphertext. The receiver inverts the substitution on the ciphertext to recover the plaintext. In classical cryptography, there are four types of substitution ciphers:

— A simple substitution cipher, or monoalphabetic cipher, is one in which each character of the plaintext is replaced with a corresponding character of ciphertext. The cryptograms in newspapers are simple substitution ciphers.

— A homophonic substitution cipher is like a simple substitution cryptosystem, except a single character of plaintext can map to one of several characters of ciphertext. For example, “A” could correspond to either 5, 13, 25, or 56, “B” could correspond to either 7, 19, 31, or 42, and so on.

— A polygram substitution cipher is one in which blocks of characters are encrypted in groups. For example, “ABA” could correspond to “RTQ,” “ABB” could correspond to “SLL,” and so on.

— A polyalphabetic substitution cipher is made up of multiple simple substitution ciphers. For example, there might be five different simple substitution ciphers used; the particular one used changes with the position of each character of the plaintext.

The famous Caesar Cipher, in which each plaintext character is replaced by the character three to the right modulo 26 (“A” is replaced by “D,” “B” is replaced by “E,”…, “W” is replaced by “Z,” “X” is replaced by “A,” “Y” is
replaced by “B,” and “Z” is replaced by “C”) is a simple substitution cipher. It’s actually even simpler, because the ciphertext alphabet is a rotation of the plaintext alphabet and not an arbitrary permutation.

ROT13 is a simple encryption program commonly found on UNIX systems; it is also a simple substitution cipher. In this cipher, “A” is replaced by “N,” “B” is replaced by “O,” and so on. Every letter is rotated 13 places. Encrypting a file twice with ROT13 restores the original file.

P = ROT13 (ROT13 (P))

ROT13 is not intended for security; it is often used in Usenet posts to hide potentially offensive text, to avoid giving away the solution to a puzzle, and so forth.

Simple substitution ciphers can be easily broken because the cipher does not hide the underlying frequencies of the different letters of the plaintext. All it takes is about 25 English characters before a good cryptanalyst can reconstruct the plaintext [1434]. An algorithm for solving these sorts of ciphers can be found in [578,587,1600,78,1475,1236,880]. A good computer algorithm is [703].

Homophonic substitution ciphers were used as early as 1401 by the Duchy of Mantua [794]. They are much more complicated to break than simple substitution ciphers, but still do not obscure all of the statistical properties of the plaintext language. With a known-plaintext attack, the ciphers are trivial to break. A ciphertext-only attack is harder, but only takes a few seconds on a computer. Details are in [1261].

Polygram substitution ciphers are ciphers in which groups of letters are encrypted together. The Playfair cipher, invented in 1854, was used by the British during World War I [794]. It encrypts pairs of letters together. Its cryptanalysis is discussed in [587,1475,880]. The Hill cipher is another example of a polygram substitution cipher [732]. Sometimes you see Huffman coding used as a cipher; this is an insecure polygram substitution cipher.

Polyalphabetic substitution ciphers were invented by Leon Battista in 1568 [794]. They were used by the Union army during the American Civil War. Despite the fact that they can be broken easily [819,577,587,794] (especially with the help of computers), many commercial computer security products use ciphers of this form [1387,1390,1502]. (Details on how to break this encryption scheme, as used in WordPerfect, can be found in [135,139].) The Vigenère cipher, first published in 1586, and the Beaufort cipher are also examples of polyalphabetic substitution ciphers.

Polyalphabetic substitution ciphers have multiple one-letter keys, each of which is used to encrypt one letter of the plaintext. The first key encrypts the first letter of the plaintext, the second key encrypts the second letter of the plaintext, and so on. After all the keys are used, the keys are recycled. If there were 20 one-letter keys, then every twentieth letter would be encrypted with the same key. This is called the period of the cipher. In classical cryptography, ciphers with longer periods were significantly harder to break than ciphers with short periods. There are computer techniques that can easily break substitution ciphers with very long periods.

A running-key cipher—sometimes called a book cipher—in which one text is used to encrypt another text, is another example of this sort of cipher. Even though this cipher has a period the length of the text, it can also be broken easily [576,794].

Buy book here: Amazon.com — Applied Cryptography