九游平台/ 对象存储服务 obs/ sdk参考/ go/ / 服务端加密(go sdk)
更新时间:2024-12-09 gmt 08:00

服务端加密(go sdk)-九游平台

功能说明

用户可以使用普通方式上传、下载对象,也可以使用服务端加密方式进行上传、下载对象。

obs支持服务端加密功能,使加密的行为在服务端进行。

用户可以根据自身的需求,使用不同的密钥管理方式来使用服务端加密功能。当前支持两种服务端加密方式: kms托管密钥的服务端加密(sse-kms)和客户提供加密密钥的服务端加密(sse-c)。上述两种方式都采用行业标准的aes256加密算法。

sse-kms方式,obs使用kms(key management service)服务提供的密钥进行服务端加密。

sse-c方式,obs使用用户提供的密钥和密钥的md5值进行服务端加密。

使用服务端加密,返回的etag值不是对象的md5值。无论是否使用服务端加密上传对象,请求消息头中加入content-md5参数时,obs均会对对象进行md5校验。

更多关于服务端加密的内容请参考服务端加密

接口约束

  • 您必须是桶拥有者或拥有上传对象的权限,才能上传对象。建议使用iam或桶策略进行授权,如果使用iam则需授予obs:object:putobject权限,如果使用桶策略则需授予putobject权限。相关授权方式介绍可参见obs权限控制概述,配置方式详见、。
  • obs支持的region与endpoint的对应关系,详细信息请参见。

方法定义

func (obsclient obsclient) putfile(input *putfileinput, extensions...extensionoptions) (output *putobjectoutput, err error)

支持接口

obs go sdk支持服务端加密的接口见下表:

obs go sdk接口方法

描述

支持加密类型

obsclient.putobject

上传对象时设置加密算法、密钥,对对象启用服务端加密。

sse-kms

sse-c

obsclient.putfile

上传文件时设置加密算法、密钥,对对象启用服务端加密。

sse-kms

sse-c

obsclient.getobject

下载对象时设置解密算法、密钥,用于解密对象。

sse-c

obsclient.copyobject

  1. 复制对象时设置源对象的解密算法、密钥,用于解密源对象。
  2. 复制对象时设置目标对象的加密算法、密钥,对目标对象启用加密算法。

sse-kms

sse-c

obsclient.getobjectmetadata

获取对象元数据时设置解密算法、密钥,用于解密对象。

sse-c

obsclient.initiatemultipartupload

初始化分段上传任务时设置加密算法、密钥,对分段上传任务最终生成的对象启用服务端加密。

sse-kms

sse-c

obsclient.uploadpart

上传段时设置加密算法、密钥,对分段数据启用服务端加密。

sse-c

obsclient.copypart

  1. 复制段时设置源对象的解密算法、密钥,用于解密源对象。
  2. 复制段时设置目标段的加密算法、密钥,对目标段启用加密算法。

sse-c

代码示例

本示例用于加密流式上传到examplebucket桶中的example/objectname对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
packagemain
import(
"crypto/md5"
"encoding/base64"
"fmt"
"os"
"strings"
obs"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)
funcmain(){
//推荐通过环境变量获取aksk,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
//您可以登录访问管理控制台获取访问密钥ak/sk,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html。
ak:=os.getenv("accesskeyid")
sk:=os.getenv("secretaccesskey")
// 【可选】如果使用临时ak/sk和securitytoken访问obs,同样建议您尽量避免使用硬编码,以降低信息泄露风险。您可以通过环境变量获取访问密钥ak/sk,也可以使用其他外部引入方式传入。
// securitytoken := os.getenv("securitytoken")
// endpoint填写bucket对应的endpoint, 这里以华北-北京四为例,其他地区请按实际情况填写。
endpoint:="https://obs.cn-north-4.myhuaweicloud.com"
// 创建obsclient实例
// 如果使用临时aksk和securitytoken访问obs,需要在创建实例时通过obs.withsecuritytoken方法指定securitytoken值。
obsclient,err:=obs.new(ak,sk,endpoint/*, obs.withsecuritytoken(securitytoken)*/)
iferr!=nil{
fmt.printf("create obsclient error, errmsg: %s",err.error())
}
input:=&obs.putobjectinput{}
// 指定存储桶名称
input.bucket="examplebucket"
// 指定上传对象名,此处以 example/objectname 为例。
input.key="example/objectname"
// 指定上传的内容
input.body=strings.newreader("hello obs")
// 指定服务端加密头信息,此处以 obs.ssecheader为例
key:=os.getenv("key")
digest:=md5.new()
digest.write([]byte(key))
bodyhash:=digest.sum(nil)
input.sseheader=obs.ssecheader{
encryption:"aes256",
key:base64.stdencoding.encodetostring([]byte(key)),// 32byteslongsecretkeymustprovided
keymd5:base64.stdencoding.encodetostring(bodyhash),
}
// 流式上传本地文件
output,err:=obsclient.putobject(input)
iferr==nil{
fmt.printf("put object(%s) under the bucket(%s) successful!\n",input.key,input.bucket)
fmt.printf("requestid:%s\n",output.requestid)
fmt.printf("storageclass:%s, etag:%s\n",
output.storageclass,output.etag)
return
}
fmt.printf("put object(%s) under the bucket(%s) fail!\n",input.key,input.bucket)
ifobserror,ok:=err.(obs.obserror);ok{
fmt.println("an obserror was found, which means your request sent to obs was rejected with an error response.")
fmt.println(obserror.error())
}else{
fmt.println("an exception was found, which means the client encountered an internal problem when attempting to communicate with obs, for example, the client was unable to access the network.")
fmt.println(err)
}
}

本示例用于流式下载examplebucket桶中的example/objectname加密对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
packagemain
import(
"crypto/md5"
"encoding/base64"
"fmt"
"os"
obs"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)
funcmain(){
// 您可以通过环境变量获取访问密钥ak/sk,也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
// 您可以登录访问管理控制台获取访问密钥ak/sk,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
ak:=os.getenv("accesskeyid")
sk:=os.getenv("secretaccesskey")
// 【可选】如果使用临时ak/sk和securitytoken访问obs,同样建议您尽量避免使用硬编码,以降低信息泄露风险。您可以通过环境变量获取访问密钥ak/sk,也可以使用其他外部引入方式传入。
// securitytoken := os.getenv("securitytoken")
// endpoint填写bucket对应的endpoint, 这里以华北-北京四为例,其他地区请按实际情况填写。
endpoint:="https://obs.cn-north-4.myhuaweicloud.com"
// 创建obsclient实例
// 如果使用临时aksk和securitytoken访问obs,需要在创建实例时通过obs.withsecuritytoken方法指定securitytoken值。
obsclient,err:=obs.new(ak,sk,endpoint/*, obs.withsecuritytoken(securitytoken)*/)
iferr!=nil{
fmt.printf("create obsclient error, errmsg: %s",err.error())
}
input:=&obs.getobjectinput{}
// 指定存储桶名称
input.bucket="examplebucket"
// 指定下载对象,此处以 example/objectname 为例。
input.key="example/objectname"
// 指定服务端加密头信息,此处以 obs.ssecheader为例
key:=os.getenv("key")
digest:=md5.new()
digest.write([]byte(key))
bodyhash:=digest.sum(nil)
input.sseheader=obs.ssecheader{
encryption:"aes256",
key:base64.stdencoding.encodetostring([]byte(key)),// 32byteslongsecretkeymustprovided
keymd5:base64.stdencoding.encodetostring(bodyhash),
}
// 流式下载对象
output,err:=obsclient.getobject(input)
iferr==nil{
// output.body 在使用完毕后必须关闭,否则会造成连接泄漏。
deferoutput.body.close()
fmt.printf("get object(%s) under the bucket(%s) successful!\n",input.key,input.bucket)
fmt.printf("storageclass:%s, etag:%s, contenttype:%s, contentlength:%d, lastmodified:%s\n",
output.storageclass,output.etag,output.contenttype,output.contentlength,output.lastmodified)
// 读取对象内容
p:=make([]byte,1024)
varreaderrerror
varreadcountint
for{
readcount,readerr=output.body.read(p)
ifreadcount>0{
fmt.printf("%s",p[:readcount])
}
ifreaderr!=nil{
break
}
}
return
}
fmt.printf("list objects under the bucket(%s) fail!\n",input.bucket)
ifobserror,ok:=err.(obs.obserror);ok{
fmt.println("an obserror was found, which means your request sent to obs was rejected with an error response.")
fmt.println(obserror.error())
}else{
fmt.println("an exception was found, which means the client encountered an internal problem when attempting to communicate with obs, for example, the client was unable to access the network.")
fmt.println(err)
}
}

相关链接

  • 关于服务端加密的api说明,请参见。
  • 更多关于服务端加密的示例代码,请参见。
  • 服务端加密接口返回的错误码含义、问题原因及处理措施可参考obs错误码

相关文档

网站地图