Last active
May 17, 2024 08:50
-
-
Save daison12006013/b8eff28902592c8e9f577874236f9e18 to your computer and use it in GitHub Desktop.
Encrypt/Obfuscate payload Javascript to Golang
This file contains 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
package main | |
import ( | |
"crypto/aes" | |
"crypto/cipher" | |
"crypto/rand" | |
"encoding/binary" | |
"encoding/hex" | |
"encoding/json" | |
"fmt" | |
"io" | |
"log" | |
"net/http" | |
"runtime" | |
"time" | |
"github.com/patrickmn/go-cache" | |
) | |
var c = cache.New(3*time.Second, 5*time.Second) | |
type ErrorStatus struct { | |
Error error | |
Message string | |
Status int | |
} | |
func generateKeyHandler(w http.ResponseWriter, r *http.Request) { | |
key := make([]byte, 32) | |
if _, err := rand.Read(key); err != nil { | |
panic(ErrorStatus{ | |
Error: err, | |
Message: "rand.Read(...) Error: " + err.Error(), | |
Status: http.StatusInternalServerError, | |
}) | |
} | |
keyStr := hex.EncodeToString(key) | |
c.Set(keyStr, key, cache.DefaultExpiration) | |
json.NewEncoder(w).Encode(map[string]string{"key": keyStr}) | |
} | |
func enableCors(w *http.ResponseWriter) { | |
(*w).Header().Set("Access-Control-Allow-Origin", "*") | |
(*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") | |
(*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") | |
} | |
type Payload struct { | |
Data string `json:"data"` | |
Key string `json:"key"` | |
} | |
func decryptData(encryptedData, key string) (map[string]interface{}, error) { | |
// Convert the hex-encoded key to bytes. | |
keyBytes, err := hex.DecodeString(key) | |
if err != nil { | |
return nil, fmt.Errorf("failed to decode key: %v", err) | |
} | |
// Convert the hex-encoded encrypted data to bytes. | |
encryptedBytes, err := hex.DecodeString(encryptedData) | |
if err != nil { | |
return nil, fmt.Errorf("failed to decode encrypted data: %v", err) | |
} | |
// Create the AES block cipher. | |
block, err := aes.NewCipher(keyBytes) | |
if err != nil { | |
return nil, fmt.Errorf("failed to create cipher: %v", err) | |
} | |
// Initialize the counter (CTR) mode with a starting value of 5. | |
// Creating the nonce with the initial counter value. | |
nonce := make([]byte, aes.BlockSize) | |
binary.BigEndian.PutUint64(nonce[aes.BlockSize-8:], uint64(5)) | |
stream := cipher.NewCTR(block, nonce) | |
// Decrypt the data. | |
decryptedBytes := make([]byte, len(encryptedBytes)) | |
stream.XORKeyStream(decryptedBytes, encryptedBytes) | |
// Convert the decrypted bytes to a string. | |
decryptedText := string(decryptedBytes) | |
// Parse the JSON from the decrypted string. | |
var result map[string]interface{} | |
err = json.Unmarshal([]byte(decryptedText), &result) | |
if err != nil { | |
return nil, fmt.Errorf("failed to unmarshal JSON: %v", err) | |
} | |
return result, nil | |
} | |
func payloadHandler(w http.ResponseWriter, r *http.Request) { | |
var payload Payload | |
body, err := io.ReadAll(r.Body) | |
if err != nil { | |
panic(ErrorStatus{ | |
Error: err, | |
Message: "io.ReadAll(...) Error: " + err.Error(), | |
Status: http.StatusBadRequest, | |
}) | |
} | |
err = json.Unmarshal(body, &payload) | |
if err != nil { | |
panic(ErrorStatus{ | |
Error: err, | |
Message: "json.Unmarshal(...) Error: " + err.Error(), | |
Status: http.StatusBadRequest, | |
}) | |
} | |
_, found := c.Get(payload.Key) | |
if !found { | |
panic(ErrorStatus{ | |
Error: fmt.Errorf("invalid key"), | |
Message: "Invalid key", | |
Status: http.StatusBadRequest, | |
}) | |
} | |
data, err := decryptData(payload.Data, payload.Key) | |
if err != nil { | |
panic(ErrorStatus{ | |
Error: err, | |
Message: "decryptData(...) Error: " + err.Error(), | |
Status: http.StatusBadRequest, | |
}) | |
} | |
// fmt.Fprintf(w, "Received data: %+v", json.MarshalIndent(data, "", " ")) | |
json.NewEncoder(w).Encode(data) | |
w.Header().Set("Content-Type", "application/json") | |
} | |
func corsMiddleware(next http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
enableCors(&w) | |
if r.Method == "OPTIONS" { | |
w.WriteHeader(http.StatusOK) | |
return | |
} | |
next.ServeHTTP(w, r) | |
}) | |
} | |
func main() { | |
mux := http.NewServeMux() | |
mux.HandleFunc("/generate-key", generateKeyHandler) | |
mux.HandleFunc("/payload", payloadHandler) | |
handler := corsMiddleware(mux) | |
fmt.Println("Server is listening on port 8080...") | |
log.Fatal(http.ListenAndServe(":8080", logRequestErrors(handler))) | |
} | |
func logRequestErrors(handler http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
defer func() { | |
if err := recover(); err != nil { | |
errStatus, ok := err.(ErrorStatus) | |
if ok { | |
log.Printf("Request error: %v", errStatus.Message) | |
http.Error(w, errStatus.Message, errStatus.Status) | |
} else { | |
log.Printf("Unknown error: %v", err) | |
http.Error(w, "Internal Server Error", http.StatusInternalServerError) | |
} | |
// Find the file and line number of the panic | |
const size = 64 << 10 | |
buf := make([]byte, size) | |
buf = buf[:runtime.Stack(buf, false)] | |
_, file, line, _ := runtime.Caller(1) | |
fmt.Printf("\npanic occurred in file %s at line %d: %v: %s", file, line, err, buf) | |
} | |
}() | |
handler.ServeHTTP(w, r) | |
}) | |
} |
This file contains 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
const apiUrl = 'http://localhost:8080'; | |
async function getEncryptionKey() { | |
const response = await fetch(`${apiUrl}/generate-key`); | |
const data = await response.json(); | |
return data.key; | |
} | |
function encryptData(data, key) { | |
let jsonBytes = aesjs.utils.utf8.toBytes(JSON.stringify(data)); | |
let keyBytes = aesjs.utils.hex.toBytes(key); | |
let aesCtr = new aesjs.ModeOfOperation.ctr(keyBytes, new aesjs.Counter(5)); | |
let encryptedBytes = aesCtr.encrypt(jsonBytes); | |
let encryptedData = aesjs.utils.hex.fromBytes(encryptedBytes); | |
return encryptedData; | |
} | |
async function sendDataToServer(data) { | |
const key = await getEncryptionKey(); | |
const encryptedData = encryptData(data, key); | |
const response = await fetch(`${apiUrl}/payload`, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ key: key, data: encryptedData }) | |
}); | |
if (response.ok) { | |
console.log('Data sent successfully.'); | |
} else { | |
console.error('Error sending data.'); | |
} | |
} | |
document.addEventListener('DOMContentLoaded', async () => { | |
var data = { | |
"name": "John Doe", | |
"email": "[email protected]" | |
}; | |
try { | |
await sendDataToServer(data); | |
} catch (error) { | |
console.error('Error:', error); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment