Last active
February 19, 2022 06:01
-
-
Save redwrasse/dd0c7823026cde99b1b4aac8b8b3dac8 to your computer and use it in GitHub Desktop.
A mock reference monitor for accessing a top secret recipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A mock reference monitor design for a mock security system, enforcing the following access control policy: | |
// Only the user 'Alice' who identifies herself on requested inputs | |
// with her name and her birthday of '01.01.1980' is granted access to | |
// the top secret recipe file, stored on disk. | |
// This reference monitor design provides (some) security towards the given access policy | |
// by a) storing a hash rather than the values of the user inputs of (name, birthday) to compare against, | |
// and b) using a salt of the valid inputs as a symmetric key for AES encrypting the top secret recipe file beforehand and | |
// for decrypting before returning to Alice. | |
// | |
// Of course these comments would not be kept in the source code. | |
// | |
// Existing threat vectors: | |
// i) A simple brute-force attack. | |
// ... | |
// | |
/// | |
// To run: save contents 'mvPVCvfYkKW51Vd9vcU7YVdiQol6TDlpL1vQT0WtNQi2qzI41yBcHexQgOx5d7_qoflLEg==' | |
// to a file called 'top_secret_encrypted', and start main(). | |
package main | |
import ( | |
"bufio" | |
"crypto/aes" | |
"crypto/cipher" | |
"crypto/rand" | |
"crypto/sha256" | |
"encoding/base64" | |
"errors" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"os" | |
"strings" | |
) | |
const CORRECT_INPUT = "VpRFAorxBrk6n_VmCZXLLL4CWHi95G7KpBRmcBc3Ltk=" | |
const SALT = "foo1234567890123" | |
func main() { | |
reader := bufio.NewReader(os.Stdin) | |
fmt.Println("Enter name: ") | |
name, _ := reader.ReadString('\n') | |
name = strings.TrimSuffix(name, "\n"); | |
fmt.Println("Enter birthday: ") | |
birthday, _ := reader.ReadString('\n') | |
birthday = strings.TrimSuffix(birthday, "\n") | |
if checkInputs(name, birthday) { | |
dat := decryptFile(name, birthday) | |
fmt.Printf("Top secret recipe file contents:\n%s\n", string(dat)) | |
} | |
} | |
func decryptFile(name string, birthday string) string { | |
dat, err := ioutil.ReadFile("./top_secret_encrypted") | |
check(err) | |
bdat, err2 := base64.URLEncoding.DecodeString(string(dat)) | |
check(err2) | |
key := []byte(name + "|" + birthday + SALT) | |
dec, err3 := decrypt(key, bdat); | |
check(err3) | |
return string(dec) | |
} | |
func inputsHash(name string, birthday string) string { | |
return hash256(name + "|" + birthday) | |
} | |
func hash256(s string) string { | |
h := sha256.New() | |
h.Write([]byte(s)) | |
sha := base64.URLEncoding.EncodeToString(h.Sum(nil)) | |
return sha | |
} | |
func checkInputs(name string, birthday string) bool { | |
sha := inputsHash(name, birthday) | |
if sha == CORRECT_INPUT { | |
fmt.Println("Correct inputs. Proceeding ...") | |
return true | |
} else { | |
fmt.Println("Incorrect. Exiting.") | |
return false | |
} | |
} | |
func check(e error) { | |
if e != nil { panic(e) } | |
} | |
func encrypt(key []byte, text []byte) ([]byte, error) { | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
return nil, err | |
} | |
b := base64.StdEncoding.EncodeToString(text) | |
ciphertext := make([]byte, aes.BlockSize+len(b)) | |
iv := ciphertext[:aes.BlockSize] | |
if _, err := io.ReadFull(rand.Reader, iv); err != nil { | |
return nil, err | |
} | |
cfb := cipher.NewCFBEncrypter(block, iv) | |
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) | |
return ciphertext, nil | |
} | |
func decrypt(key []byte, text []byte) ([]byte, error) { | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
return nil, err | |
} | |
if len(text) < aes.BlockSize { | |
return nil, errors.New("ciphertext too short") | |
} | |
iv := text[:aes.BlockSize] | |
text = text[aes.BlockSize:] | |
cfb := cipher.NewCFBDecrypter(block, iv) | |
cfb.XORKeyStream(text, text) | |
data, err := base64.StdEncoding.DecodeString(string(text)) | |
if err != nil { | |
return nil, err | |
} | |
return data, nil | |
} |
Author
redwrasse
commented
Feb 19, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment