2 people like it.

Decrypting a Rijndael string

This F# code decrypts an encrypted string using Rijndael symmetric encryption algorithm. It uses key and initialization vector stored in a registry key.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
open System.IO
open System.Security.Cryptography
open System.Text
open System.Diagnostics.Contracts

let DeCryptStringWith (crypted:string) (key:string) (iv:string) = 
    let enc = new ASCIIEncoding()
    let algo = Rijndael.Create()
    if(crypted.Length < 5) then 
        failwith "Crypted string length has to be over 5 chars."
    use decrypted = new MemoryStream()
    use decode = new FromBase64Transform()
    let errdesc = "Failure when decrypting the string " + crypted.[0..3] + "...\r\n"
    try
        use decryptor = algo.CreateDecryptor(enc.GetBytes(key), enc.GetBytes(iv))
        use tmpcrypt = new CryptoStream(decrypted, decryptor, CryptoStreamMode.Write)
        use decodestream = new CryptoStream(tmpcrypt, decode, CryptoStreamMode.Write)
        let cryptedbytes = enc.GetBytes(crypted);
        decodestream.Write(cryptedbytes, 0, cryptedbytes.Length);
        decodestream.Close() // lazy, has to close explicitly before use. using is not enough.
    with
        | :? CryptographicException as ex -> failwith(errdesc + ex.ToString())
        | :? System.FormatException as ex -> failwith(errdesc + ex.ToString())
    enc.GetString(decrypted.ToArray())

(Function to read registry keys omitted)

// I recommend to get key and iv from registry 
// and then make one more method like:
let internal DeCryptString crypted =
    let key = GetRegistryValue("rgbKey").ToString()
    let iv = GetRegistryValue("rgbIV").ToString()
    DeCryptStringWith crypted key iv
namespace System
namespace System.IO
namespace System.Security
namespace System.Security.Cryptography
namespace System.Text
namespace System.Diagnostics
namespace System.Diagnostics.Contracts
val DeCryptStringWith : crypted:string -> key:string -> iv:string -> string
val crypted : string
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
val key : string
val iv : string
val enc : ASCIIEncoding
Multiple items
type ASCIIEncoding =
  inherit Encoding
  new : unit -> ASCIIEncoding
  member GetByteCount : chars:string -> int + 3 overloads
  member GetBytes : chars:ReadOnlySpan<char> * bytes:Span<byte> -> int + 3 overloads
  member GetCharCount : bytes:ReadOnlySpan<byte> -> int + 2 overloads
  member GetChars : bytes:ReadOnlySpan<byte> * chars:Span<char> -> int + 2 overloads
  member GetDecoder : unit -> Decoder
  member GetEncoder : unit -> Encoder
  member GetMaxByteCount : charCount:int -> int
  member GetMaxCharCount : byteCount:int -> int
  member GetString : bytes:byte[] * byteIndex:int * byteCount:int -> string
  ...

--------------------
ASCIIEncoding() : ASCIIEncoding
val algo : Rijndael
type Rijndael =
  inherit SymmetricAlgorithm
  static member Create : unit -> Rijndael + 1 overload
Rijndael.Create() : Rijndael
Rijndael.Create(algName: string) : Rijndael
val failwith : message:string -> 'T
val decrypted : MemoryStream
Multiple items
type MemoryStream =
  inherit Stream
  new : unit -> MemoryStream + 6 overloads
  member CanRead : bool
  member CanSeek : bool
  member CanWrite : bool
  member Capacity : int with get, set
  member CopyTo : destination:Stream * bufferSize:int -> unit
  member CopyToAsync : destination:Stream * bufferSize:int * cancellationToken:CancellationToken -> Task
  member Flush : unit -> unit
  member FlushAsync : cancellationToken:CancellationToken -> Task
  member GetBuffer : unit -> byte[]
  ...

--------------------
MemoryStream() : MemoryStream
MemoryStream(capacity: int) : MemoryStream
MemoryStream(buffer: byte []) : MemoryStream
MemoryStream(buffer: byte [], writable: bool) : MemoryStream
MemoryStream(buffer: byte [], index: int, count: int) : MemoryStream
MemoryStream(buffer: byte [], index: int, count: int, writable: bool) : MemoryStream
MemoryStream(buffer: byte [], index: int, count: int, writable: bool, publiclyVisible: bool) : MemoryStream
val decode : FromBase64Transform
Multiple items
type FromBase64Transform =
  new : unit -> FromBase64Transform + 1 overload
  member CanReuseTransform : bool
  member CanTransformMultipleBlocks : bool
  member Clear : unit -> unit
  member Dispose : unit -> unit
  member InputBlockSize : int
  member OutputBlockSize : int
  member TransformBlock : inputBuffer:byte[] * inputOffset:int * inputCount:int * outputBuffer:byte[] * outputOffset:int -> int
  member TransformFinalBlock : inputBuffer:byte[] * inputOffset:int * inputCount:int -> byte[]

--------------------
FromBase64Transform() : FromBase64Transform
FromBase64Transform(whitespaces: FromBase64TransformMode) : FromBase64Transform
val errdesc : string
val decryptor : ICryptoTransform
val tmpcrypt : CryptoStream
Multiple items
type CryptoStream =
  inherit Stream
  new : stream:Stream * transform:ICryptoTransform * mode:CryptoStreamMode -> CryptoStream + 1 overload
  member BeginRead : buffer:byte[] * offset:int * count:int * callback:AsyncCallback * state:obj -> IAsyncResult
  member BeginWrite : buffer:byte[] * offset:int * count:int * callback:AsyncCallback * state:obj -> IAsyncResult
  member CanRead : bool
  member CanSeek : bool
  member CanWrite : bool
  member Clear : unit -> unit
  member DisposeAsync : unit -> ValueTask
  member EndRead : asyncResult:IAsyncResult -> int
  member EndWrite : asyncResult:IAsyncResult -> unit
  ...

--------------------
CryptoStream(stream: Stream, transform: ICryptoTransform, mode: CryptoStreamMode) : CryptoStream
CryptoStream(stream: Stream, transform: ICryptoTransform, mode: CryptoStreamMode, leaveOpen: bool) : CryptoStream
type CryptoStreamMode =
  | Read = 0
  | Write = 1
field CryptoStreamMode.Write: CryptoStreamMode = 1
val decodestream : CryptoStream
val cryptedbytes : byte []
Multiple items
type CryptographicException =
  inherit SystemException
  new : unit -> CryptographicException + 4 overloads

--------------------
CryptographicException() : CryptographicException
CryptographicException(hr: int) : CryptographicException
CryptographicException(message: string) : CryptographicException
CryptographicException(message: string, inner: exn) : CryptographicException
CryptographicException(format: string, insert: string) : CryptographicException
val ex : CryptographicException
Multiple items
type FormatException =
  inherit SystemException
  new : unit -> FormatException + 2 overloads

--------------------
System.FormatException() : System.FormatException
System.FormatException(message: string) : System.FormatException
System.FormatException(message: string, innerException: exn) : System.FormatException
val ex : System.FormatException
let REGISTRYSOFTWARE = "Software";
let REGISTRYMYPATH = "MySoftware";

let GetRegistryValue key =
    use path1 = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(REGISTRYSOFTWARE)
    match path1 with
    | null -> failwith("Access failed to registry: hklm\\"+REGISTRYSOFTWARE)
    | keyhklmsw ->
        use path2 = keyhklmsw.OpenSubKey(REGISTRYMYPATH)
        match path2 with
        | null -> failwith("Access failed to registry: " + REGISTRYMYPATH)
        | keyhklmswmypath ->
            match keyhklmswmypath.GetValue(key, null) with
            | null -> failwith("Path not found: " + key)
            | gotkey -> gotkey
val internal DeCryptString : crypted:string -> string
val GetRegistryValue : key:string -> obj

More information

Link:http://fssnip.net/1n
Posted:2 years ago
Author:Tuomas Hietanen
Tags: rijndael , decrypt , cryptography