This script can be used to generate unique keys from credential files in an AWS S3 bucket. If we needed a key that was a hash of the ClientID and Client Secret, then we can use the below script to find a key for every file in a given S3 bucket. This script will use the .aws
credential file on the machine that it is running on.
package main
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"io/ioutil"
"log"
"os"
"fmt"
)
// Downloads an item from an S3 Bucket in the region configured in the shared config
// or AWS_REGION environment variable.
//
func main() {
if len(os.Args) != 2 {
exitErrorf("Bucket name required\nUsage: %s bucket_name",
os.Args[0])
}
bucket := os.Args[1]
// Initialize a session in us-east-1
// credentials from the shared credentials file ~/.aws/credentials.
sess, _ := session.NewSession(&aws.Config{
Region: aws.String("us-east-1")},
)
// gather arguments for the ListObjects() function
input := &s3.ListObjectsInput{
Bucket: aws.String(bucket),
MaxKeys: aws.Int64(20),
}
// S3 service
svc := s3.New(sess)
// List all the objects in the bucket
results, err := svc.ListObjects(input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case s3.ErrCodeNoSuchBucket:
fmt.Println(s3.ErrCodeNoSuchBucket, aerr.Error())
default:
fmt.Println(aerr.Error())
}
} else {
fmt.Println(err.Error())
}
return
}
// Log list results if needed
//fmt.Println(results)
// Downloader for S3
downloader := s3manager.NewDownloader(sess)
// Temp file from ioutil
tmpFile, err := ioutil.TempFile("", "tmp")
if err != nil {
log.Fatal(err)
}
// Create API key for every file in S3
for _, file := range results.Contents {
// Get file from s3 and put in tmp file
// replace _ with numBytes for logging below to work
_, err = downloader.Download(tmpFile,
&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(*file.Key),
})
if err != nil {
exitErrorf("Unable to download item %q, %v", file.Key, err)
}
//Logging if needed
//fmt.Println("Downloaded", *file.Key, numBytes, "bytes")
// Output the API key
byteValue, _ := ioutil.ReadAll(tmpFile)
var client Client
_ = json.Unmarshal([]byte(byteValue), &client)
fmt.Println("API key for: ", *file.Key, "\n", client.generateKey())
}
defer os.Remove(tmpFile.Name()) // clean up
}
func exitErrorf(msg string, args ...interface{}) {
_, _ = fmt.Fprintf(os.Stderr, msg+"\n", args...)
os.Exit(1)
}
// Client : Struct to represent the client files in S3
type Client struct {
ClientSecret string `json:"clientSecret"`
RedirectUrls string `json:"redirectUrls"`
Name string `json:"name"`
ClientId string `json:"clientId"`
Description string `json:"description"`
}
// Function to calculate a clients API Key
func (c Client) generateKey() string {
// like PrintF but returns the string without printing
comb := fmt.Sprintf("%v%v", c.ClientId, c.ClientSecret)
myBytes := sha256.Sum256([]byte(comb))
return hex.EncodeToString(myBytes[:])
}
Usage:
go run {scriptName}.go {bucketName}