Skip to content

Instantly share code, notes, and snippets.

@scriptpapi
Created April 17, 2026 10:49
Show Gist options
  • Select an option

  • Save scriptpapi/33b19bf267d055f3b8f888a6f762ca36 to your computer and use it in GitHub Desktop.

Select an option

Save scriptpapi/33b19bf267d055f3b8f888a6f762ca36 to your computer and use it in GitHub Desktop.
const crypto = require("crypto");
const fs = require("fs");
const accessKey = "YOUR_ACCESS_KEY";
const secretKey = "YOUR_SECRET_KEY";
const region = "YOUR_REGION";
const service = "s3";
const host = "YOUR_NAMESPACE.compat.objectstorage.YOUR_REGION.oraclecloud.com";
function sha256Buffer(buffer) {
return crypto.createHash("sha256").update(buffer).digest("hex");
}
function sha256String(data) {
return crypto.createHash("sha256").update(data, "utf8").digest("hex");
}
function getSignatureKey(key, dateStamp, regionName, serviceName) {
const kDate = crypto.createHmac("sha256", "AWS4" + key).update(dateStamp).digest();
const kRegion = crypto.createHmac("sha256", kDate).update(regionName).digest();
const kService = crypto.createHmac("sha256", kRegion).update(serviceName).digest();
return crypto.createHmac("sha256", kService).update("aws4_request").digest();
}
async function uploadFile() {
const bucket = "my-bucket";
const objectKey = "test.txt";
const body = fs.readFileSync("./test.txt");
const now = new Date();
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, "");
const dateStamp = amzDate.slice(0, 8);
const method = "PUT";
const canonicalUri = `/${bucket}/${objectKey}`;
const canonicalQueryString = "";
const payloadHash = sha256Buffer(body);
const canonicalHeaders =
`host:${host}\n` +
`x-amz-content-sha256:${payloadHash}\n` +
`x-amz-date:${amzDate}\n`;
const signedHeaders = "host;x-amz-content-sha256;x-amz-date";
const canonicalRequest =
`${method}\n` +
`${canonicalUri}\n` +
`${canonicalQueryString}\n` +
`${canonicalHeaders}\n` +
`${signedHeaders}\n` +
`${payloadHash}`;
const algorithm = "AWS4-HMAC-SHA256";
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
const stringToSign =
`${algorithm}\n` +
`${amzDate}\n` +
`${credentialScope}\n` +
`${sha256String(canonicalRequest)}`;
const signingKey = getSignatureKey(secretKey, dateStamp, region, service);
const signature = crypto
.createHmac("sha256", signingKey)
.update(stringToSign, "utf8")
.digest("hex");
const authorizationHeader =
`${algorithm} Credential=${accessKey}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
const response = await fetch(`https://${host}${canonicalUri}`, {
method: "PUT",
headers: {
"x-amz-date": amzDate,
"x-amz-content-sha256": payloadHash,
"Authorization": authorizationHeader,
"Content-Type": "text/plain",
},
body,
});
const text = await response.text();
console.log("status:", response.status);
console.log(text);
}
uploadFile().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment