github.com/rajasrinivasan/spm@v0.0.0-20200125100127-755649755f3f/src/pkg/crypt.go (about) 1 package pkg 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 "crypto/rand" 8 "crypto/sha256" 9 "errors" 10 "io" 11 "io/ioutil" 12 "log" 13 "os" 14 ) 15 16 const salt = "How razorback-jumping frogs can level six piqued gymnasts!" 17 18 func generateKey(passphrase string) []byte { 19 salted := passphrase + salt 20 hash := sha256.New() 21 hash.Write([]byte(salted)) 22 return hash.Sum(nil) 23 } 24 25 func generateInitVector() []byte { 26 iv := make([]byte, aes.BlockSize) 27 _, err := rand.Read(iv) 28 if err != nil { 29 log.Printf("%s\n", err) 30 } 31 if Verbose { 32 log.Printf("IV: %x\n", iv) 33 } 34 return iv 35 } 36 37 func Encrypt(passphrase string, from string, to string) error { 38 log.Printf("Encrypt from: %s to %s passphrase %s\n", from, to, passphrase) 39 40 ofile, err := os.Create(to) 41 if err != nil { 42 log.Fatal(err) 43 } 44 defer ofile.Close() 45 46 ifile, err := os.Open(from) 47 if err != nil { 48 log.Fatal(err) 49 } 50 defer ifile.Close() 51 52 secret := generateKey(passphrase) 53 encalg, err := aes.NewCipher(secret) 54 if err != nil { 55 log.Printf("%s\n", err) 56 return err 57 } 58 59 iv := generateInitVector() 60 61 ofile.Write(secret) 62 ofile.Write(iv) 63 64 str := cipher.NewOFB(encalg, iv) 65 66 idata, _ := ioutil.ReadAll(ifile) 67 odata := make([]byte, len(idata)) 68 str.XORKeyStream(odata, idata) 69 70 ofile.Write(odata) 71 72 return nil 73 } 74 75 func Decrypt(passphrase string, from string, to string) error { 76 log.Printf("Decrypt from: %s to %s passphrase %s\n", from, to, passphrase) 77 78 ofile, err := os.Create(to) 79 if err != nil { 80 log.Fatal(err) 81 } 82 defer ofile.Close() 83 84 ifile, err := os.Open(from) 85 if err != nil { 86 log.Fatal(err) 87 } 88 defer ifile.Close() 89 90 secret := generateKey(passphrase) 91 filepass := make([]byte, len(secret)) 92 bytesin, err := io.ReadFull(ifile, filepass) 93 if err != nil { 94 log.Fatal(err) 95 } 96 if Verbose { 97 log.Printf("%d bytes read for password\n", bytesin) 98 } 99 res := bytes.Compare(secret, filepass) 100 if res != 0 { 101 log.Printf("Passphrase comparison failed\n") 102 return errors.New("Passphrase comparison failed") 103 } 104 105 iv := make([]byte, aes.BlockSize) 106 bytesin, err = io.ReadFull(ifile, iv) 107 if err != nil { 108 log.Fatal(err) 109 } 110 if Verbose { 111 log.Printf("%d bytes read for IV\n", bytesin) 112 log.Printf("IV: %x\n", iv) 113 } 114 encalg, err := aes.NewCipher(filepass) 115 if err != nil { 116 log.Printf("%s\n", err) 117 return err 118 } 119 st, _ := os.Stat(from) 120 buf := make([]byte, int(st.Size())-len(secret)-len(iv)) 121 nbytesin, err := io.ReadFull(ifile, buf) 122 if err != nil { 123 log.Fatal(err) 124 } 125 if Verbose { 126 log.Printf("%d bytes read\n", nbytesin) 127 } 128 obuf := make([]byte, len(buf)) 129 130 str := cipher.NewOFB(encalg, iv) 131 str.XORKeyStream(obuf, buf) 132 133 nbytesout, err := ofile.Write(obuf) 134 if err != nil { 135 log.Fatal(err) 136 } 137 if Verbose { 138 log.Printf("%d bytes written\n", nbytesout) 139 } 140 ofile.Close() 141 return nil 142 }