You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UniBasic/UniData中使用AWS Signature Version 4通过REST API上传文件至Amazon S3

UniBasic/UniData 调用AWS S3 REST API(Signature Version 4认证)上传文件示例

以下是直接在UniBasic中构造S3 PUT请求并通过SigV4认证的实现示例,包含核心签名生成逻辑和文件上传主程序:

1. 核心SigV4签名生成函数

这个函数负责生成AWS Signature Version 4所需的Authorization头部,处理日期、规范请求、签名密钥等关键步骤:

FUNCTION GENERATE_S3_SIGV4(ACCESS_KEY, SECRET_KEY, REGION, SERVICE, HTTP_METHOD, URL_PATH, QUERY_PARAMS, HEADERS, PAYLOAD_HASH)
* 步骤1: 生成UTC时间戳和日期戳
CALL GET_UTC_TIMESTAMP(TIME_STAMP, DATE_STAMP)

* 步骤2: 构造规范请求
CANONICAL_REQUEST = HTTP_METHOD : @AM : @AM
CANONICAL_REQUEST := CANONICAL_REQUEST : URL_PATH : @AM
CANONICAL_REQUEST := CANONICAL_REQUEST : QUERY_PARAMS : @AM
CANONICAL_REQUEST := CANONICAL_REQUEST : HEADERS : @AM : @AM
CANONICAL_REQUEST := CANONICAL_REQUEST : PAYLOAD_HASH

* 步骤3: 构造待签名字符串
STRING_TO_SIGN = "AWS4-HMAC-SHA256" : @AM
STRING_TO_SIGN := STRING_TO_SIGN : TIME_STAMP : @AM
STRING_TO_SIGN := STRING_TO_SIGN : DATE_STAMP & "/" & REGION & "/" & SERVICE & "/aws4_request" : @AM
STRING_TO_SIGN := STRING_TO_SIGN : SHA256(CANONICAL_REQUEST)

* 步骤4: 生成多层HMAC密钥
DATE_KEY = HMAC_SHA256("AWS4" : SECRET_KEY, DATE_STAMP)
DATE_REGION_KEY = HMAC_SHA256(DATE_KEY, REGION)
DATE_REGION_SERVICE_KEY = HMAC_SHA256(DATE_REGION_KEY, SERVICE)
SIGNING_KEY = HMAC_SHA256(DATE_REGION_SERVICE_KEY, "aws4_request")

* 步骤5: 计算最终签名并构造Authorization头
SIGNATURE = HEX_ENCODE(HMAC_SHA256(SIGNING_KEY, STRING_TO_SIGN))
SIGNED_HEADERS = "host,x-amz-content-sha256,x-amz-date" ;* 需与请求头中的签名头一致

AUTH_HEADER = "AWS4-HMAC-SHA256 Credential=" : ACCESS_KEY & "/" & DATE_STAMP & "/" & REGION & "/" & SERVICE & "/aws4_request,"
AUTH_HEADER := AUTH_HEADER & "SignedHeaders=" : SIGNED_HEADERS & ","
AUTH_HEADER := AUTH_HEADER & "Signature=" : SIGNATURE

RETURN AUTH_HEADER
END FUNCTION

2. 辅助工具函数

UniBasic/UniData通常没有内置的加密函数,需要通过系统命令或第三方库实现:

UTC时间戳生成

FUNCTION GET_UTC_TIMESTAMP(TIME_STAMP, DATE_STAMP)
* 返回格式: TIME_STAMP=YYYYMMDDTHHMMSSZ, DATE_STAMP=YYYYMMDD
UTC_DATE = OCONV(UTC(), "D2YMD")
UTC_TIME = OCONV(UTC(), "MTS")
DATE_STAMP = UTC_DATE
TIME_STAMP = UTC_DATE : "T" : UTC_TIME : "Z"
END FUNCTION

SHA256哈希计算(通过OpenSSL)

FUNCTION SHA256(INPUT_STR)
    TEMP_FILE = "/tmp/ub_sha256.tmp"
    OPEN LOCAL TEMP_FILE TO TEMP.FD ELSE RETURN ""
    WRITE INPUT_STR TO TEMP.FD
    CLOSE TEMP.FD
    EXECUTE "openssl dgst -sha256 -hex " : TEMP_FILE CAPTURING OUTPUT
    PARSE OUTPUT WITH " " TO * HASH
    DELETE FILE TEMP_FILE
    RETURN HASH
END FUNCTION

HMAC-SHA256计算(通过OpenSSL)

FUNCTION HMAC_SHA256(KEY, MSG)
    TEMP_KEY_FILE = "/tmp/ub_hmac_key.tmp"
    TEMP_MSG_FILE = "/tmp/ub_hmac_msg.tmp"
    
    OPEN LOCAL TEMP_KEY_FILE TO KEY.FD ELSE RETURN ""
    WRITE KEY TO KEY.FD
    CLOSE KEY.FD
    
    OPEN LOCAL TEMP_MSG_FILE TO MSG.FD ELSE RETURN ""
    WRITE MSG TO MSG.FD
    CLOSE MSG.FD
    
    EXECUTE "openssl dgst -sha256 -hmac $(cat " : TEMP_KEY_FILE : ") " : TEMP_MSG_FILE CAPTURING OUTPUT
    PARSE OUTPUT WITH " " TO * HASH
    
    DELETE FILE TEMP_KEY_FILE
    DELETE FILE TEMP_MSG_FILE
    
    RETURN HASH
END FUNCTION

十六进制编码

FUNCTION HEX_ENCODE(BIN_STR)
    HEX_STR = ""
    FOR I=1 TO LEN(BIN_STR)
        HEX_STR := HEX_STR : OCONV(SEQ(BIN_STR[I,I]), "X")
    NEXT I
    RETURN HEX_STR
END FUNCTION

3. 文件上传主程序

PROGRAM UPLOAD_TO_S3
* 配置参数
ACCESS_KEY = "YOUR_AWS_ACCESS_KEY"
SECRET_KEY = "YOUR_AWS_SECRET_KEY"
REGION = "us-east-1"
BUCKET_NAME = "your-target-bucket"
OBJECT_KEY = "documents/uploaded_file.txt" ;* S3中的对象路径
LOCAL_FILE = "/path/to/your/local/file.txt" ;* UniData本地文件路径

* 读取本地文件内容
OPEN LOCAL LOCAL_FILE TO FILE.FD ELSE
    PRINT "Error: 无法打开本地文件 " : LOCAL_FILE
    STOP
END
READSEQ FILE_CONTENT FROM FILE.FD ELSE FILE_CONTENT = ""
CLOSE FILE.FD

* 计算文件内容的SHA256哈希
PAYLOAD_HASH = SHA256(FILE_CONTENT)

* 构造请求基础信息
HTTP_METHOD = "PUT"
URL_PATH = "/" : BUCKET_NAME : "/" : OBJECT_KEY
SERVICE = "s3"
ENDPOINT = BUCKET_NAME & ".s3." & REGION & ".amazonaws.com"

* 生成请求头
CALL GET_UTC_TIMESTAMP(TIME_STAMP, DATE_STAMP)
HEADERS = "host:" : ENDPOINT : @AM
HEADERS := HEADERS & "x-amz-content-sha256:" : PAYLOAD_HASH : @AM
HEADERS := HEADERS & "x-amz-date:" : TIME_STAMP

* 获取Authorization头
CALL GENERATE_S3_SIGV4(ACCESS_KEY, SECRET_KEY, REGION, SERVICE, HTTP_METHOD, URL_PATH, "", HEADERS, PAYLOAD_HASH) TO AUTH_HEADER

* 构造完整HTTP请求
REQUEST = HTTP_METHOD : " " : URL_PATH : " HTTP/1.1" : @AM
REQUEST := REQUEST : HEADERS : @AM
REQUEST := REQUEST : "Authorization:" : AUTH_HEADER : @AM : @AM
REQUEST := REQUEST : FILE_CONTENT

* 发送HTTPS请求(示例使用curl,若UniBasic支持原生HTTPS可替换)
EXECUTE "curl -X PUT -d @- -k " : "https://" : ENDPOINT : URL_PATH : " -H 'Authorization: " : AUTH_HEADER : "' -H 'host: " : ENDPOINT : "' -H 'x-amz-content-sha256: " : PAYLOAD_HASH : "' -H 'x-amz-date: " : TIME_STAMP : "'" CAPTURING RESPONSE <@REQUEST
PRINT "S3响应: " : RESPONSE

END PROGRAM

关键注意事项

  • 权限验证:确保AWS Access Key拥有s3:PutObject权限,且Bucket策略允许该操作。
  • HTTPS支持:如果UniBasic原生不支持HTTPS请求,使用curl是简便的替代方案,也可以通过Socket配合SSL库实现原生请求。
  • 时间同步:服务器时间需与UTC时间同步,否则SigV4签名会验证失败。
  • 特殊字符处理:如果对象键或文件内容包含特殊字符,需按S3规范进行URL编码或处理。

内容的提问来源于stack exchange,提问作者Marvado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:18:33