jimeng-free-api/temp/sha256_test.html
2025-05-30 18:37:00 +08:00

210 lines
9.0 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SHA256 哈希测试</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<style>
body {
font-family: sans-serif;
margin: 20px;
background-color: #f4f4f4;
color: #333;
}
.container {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
input[type="text"] {
width: calc(100% - 22px);
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
#resultRaw,
#resultHex {
margin-top: 15px;
padding: 10px;
background-color: #e9ecef;
border: 1px solid #ced4da;
border-radius: 4px;
word-wrap: break-word;
}
h3 {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<h2>SHA256 哈希计算器</h2>
<input type="text" id="inputText" placeholder="在此输入要哈希的文本">
<button onclick="calculateHash()">计算 SHA256 哈希</button>
<h3>CryptoJS WordArray 对象:</h3>
<pre id="resultRaw"></pre>
<h3>十六进制哈希结果:</h3>
<pre id="resultHex"></pre>
</div>
<div class="container" style="margin-top: 20px;">
<h2>AWS V4 签名计算器 (模拟)</h2>
<button onclick="calculateSignature()">计算签名</button>
<h3>签名 Query:</h3>
<pre id="signatureQuery"></pre>
<h3>ISO8601 时间 (X-Amz-Date):</h3>
<pre id="isoTime"></pre>
<h3>Canonical Request:</h3>
<pre id="canonicalRequest"></pre>
<h3>String to Sign:</h3>
<pre id="stringToSign"></pre>
<h3>Authorization Header:</h3>
<pre id="authorizationHeader"></pre>
</div>
<script>
const te = {
"accessKeyId": "AKTPMTZjYTJkNWMzOWY1NDYxMmFlMmRlNDUxZTc3ODI4Yzk",
"secretAccessKey": "gWRJ+a7OLWDH+rsGUYNCSlV2r1zltBu+KNvO9TuLgzG+jrFv4ClLyVH/awi1Q3Uq",
"sessionToken": "STS2eyJMVEFjY2Vzc0tleUlEIjoiQUtMVFpUQm1ZbVl4TlRsa1ptVmpOREJqWVRrM09UUTNZbU5pTmprMk1EUXdaV00iLCJBY2Nlc3NLZXlJRCI6IkFLVFBNVFpqWVRKa05XTXpPV1kxTkRZeE1tRmxNbVJsTkRVeFpUYzNPREk0WXprIiwiU2lnbmVkU2VjcmV0QWNjZXNzS2V5IjoiN25ZU0o3T0FCMGZubHlKSENBbzcrOTMyV1FPbkUxck00ZnRuNHpPcVc2Unc1NTJJSWRnY3E1YkF6dWd0VUZaRTZPSzhUa3JBb2c3TW9GV3UzeWplZjV2Y3I2cndUWWM4dklYMzdiZ1BuSWM9IiwiRXhwaXJlZFRpbWUiOjE3NDg1OTEzMDksIlBvbGljeVN0cmluZyI6IntcIlN0YXRlbWVudFwiOlt7XCJFZmZlY3RcIjpcIkFsbG93XCIsXCJBY3Rpb25cIjpbXCJ2b2Q6QXBwbHlVcGxvYWRcIixcInZvZDpBcHBseVVwbG9hZElubmVyXCIsXCJ2b2Q6Q29tbWl0VXBsb2FkXCIsXCJ2b2Q6Q29tbWl0VXBsb2FkSW5uZXJcIixcInZvZDpHZXRVcGxvYWRDYW5kaWRhdGVzXCIsXCJJbWFnZVg6QXBwbHlJbWFnZVVwbG9hZFwiLFwiSW1hZ2VYOkNvbW1pdEltYWdlVXBsb2FkXCIsXCJJbWFnZVg6QXBwbHlVcGxvYWRJbWFnZUZpbGVcIixcIkltYWdlWDpDb21taXRVcGxvYWRJbWFnZUZpbGVcIl0sXCJSZXNvdXJjZVwiOltcIipcIl0sXCJDb25kaXRpb25cIjpcIntcXFwiUFNNXFxcIjpcXFwidmlkZW9jdXQubXdlYi5hcGlcXFwifVwifV19IiwiU2lnbmF0dXJlIjoiZTkyNGRmY2Q2ZjE4OTM1NTg5ZjBjYzk5NDc3MjkxZjU5MDk5NGE0ZGZmMGU1Mjc5YjkwZTk1NmUwY2Q0MWFlMiJ9"
}
const tq = {
"Action": "ApplyImageUpload",
"Version": "2018-08-01",
"ServiceId": "tb4s082cfz",
"FileSize": 1930510,
"s": "5sohmgy6e1p"
}
const ttt = "20250530T064830Z";
// 辅助函数:将对象转换为查询字符串
function toQueryString(obj) {
return Object.keys(obj).sort().map(key => {
return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
}).join('&');
}
// 辅助函数:生成 ISO8601 格式时间字符串 (YYYYMMDDTHHMMSSZ)
function getAmzDate(date) {
return date.toISOString().replace(/[:\-]*/g, '').split('.')[0] + 'Z';
}
function authorizationSign(accessKeyId, secretAccessKey, amzDate, queryParams, headers) {
const service = "imagex"; // 或者从其他地方获取,这里根据 getUploadService 逻辑
const region = "cn-north-1"; // 根据您的 regionStr
const method = 'GET';
const canonicalUri = '/'; // 通常是 API 的路径,这里根据 getUploadService 逻辑是根路径
// 1. 创建规范请求 (Canonical Request)
const canonicalQueryString = toQueryString(queryParams);
const signedHeaders = Object.keys(headers).map(h => h.toLowerCase()).sort().join(';');
let canonicalHeaders = '';
Object.keys(headers).sort().forEach(key => {
canonicalHeaders += key.toLowerCase() + ':' + String(headers[key]).trim() + '\n';
});
const payloadHash = CryptoJS.SHA256("").toString(CryptoJS.enc.Hex); // GET 请求通常为空 payload
const canonicalRequest =
method + '\n' +
canonicalUri + '\n' +
canonicalQueryString + '\n' +
canonicalHeaders + '\n' +
signedHeaders + '\n' +
payloadHash;
document.getElementById('canonicalRequest').textContent = canonicalRequest;
console.log("canonicalRequest",canonicalRequest);
// 2. 创建待签字符串 (String to Sign)
const dateStamp = amzDate.substring(0, 8);
const credentialScope = dateStamp + '/' + region + '/' + service + '/' + 'aws4_request';
const stringToSign =
'AWS4-HMAC-SHA256' + '\n' +
amzDate + '\n' +
credentialScope + '\n' +
CryptoJS.SHA256(canonicalRequest).toString(CryptoJS.enc.Hex);
document.getElementById('stringToSign').textContent = stringToSign;
// 3. 计算签名 (Calculate Signature)
const kDate = CryptoJS.HmacSHA256(dateStamp, 'AWS4' + secretAccessKey);
const kRegion = CryptoJS.HmacSHA256(region, kDate);
const kService = CryptoJS.HmacSHA256(service, kRegion);
const kSigning = CryptoJS.HmacSHA256('aws4_request', kService);
console.log("kSigning",kSigning.toString());
console.log("stringToSign",stringToSign);
const signature = CryptoJS.HmacSHA256(stringToSign, kSigning).toString(CryptoJS.enc.Hex);
// 4. 构建 Authorization 头部
const authorization =
'AWS4-HMAC-SHA256 Credential=' + accessKeyId + '/' + credentialScope +
', SignedHeaders=' + signedHeaders +
', Signature=' + signature;
return authorization;
}
function calculateSignature(){
const access_key_id = te.accessKeyId;
const secret_access_key = te.secretAccessKey;
const session_token = te.sessionToken;
let query = tq;
document.getElementById('signatureQuery').textContent = JSON.stringify(query, null, 4);
// const amzDate = getAmzDate(new Date()); // 使用当前时间生成 X-Amz-Date
const amzDate = ttt; // 或者使用硬编码的时间进行测试与TS代码一致
document.getElementById('isoTime').textContent = amzDate;
let headers = {
"x-amz-date": amzDate,
};
if (session_token) {
headers["x-amz-security-token"] = session_token;
}
const authorization = authorizationSign(access_key_id, secret_access_key, amzDate, query, headers);
document.getElementById('authorizationHeader').textContent = authorization;
}
function calculateHash() {
const inputText = document.getElementById('inputText').value;
if (inputText === null || inputText.trim() === '') {
document.getElementById('resultRaw').textContent = '请输入文本后再计算。';
document.getElementById('resultHex').textContent = '';
return;
}
const hash = CryptoJS.SHA256(inputText);
// 显示原始 WordArray 对象 (格式化为 JSON 字符串)
const rawResult = {
words: hash.words,
sigBytes: hash.sigBytes
};
document.getElementById('resultRaw').textContent = JSON.stringify(rawResult, null, 4);
// 显示十六进制哈希字符串
document.getElementById('resultHex').textContent = hash.toString(CryptoJS.enc.Hex);
}
</script>
</body>
</html>