Skip to content

Commit

Permalink
cse-kms done
Browse files Browse the repository at this point in the history
  • Loading branch information
jojoliang committed May 14, 2021
1 parent 70b911b commit 05379cf
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 12 deletions.
2 changes: 1 addition & 1 deletion cos.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (

const (
// Version current go sdk version
Version = "0.7.25"
Version = "0.7.26"
userAgent = "cos-go-sdk-v5/" + Version
contentTypeXML = "application/xml"
defaultServiceBaseURL = "http://service.cos.myqcloud.com"
Expand Down
33 changes: 28 additions & 5 deletions crypto/crypto_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package coscrypto

import (
"context"
"encoding/base64"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"io"
Expand Down Expand Up @@ -107,7 +108,10 @@ func (s *CryptoObjectService) Get(ctx context.Context, name string, opt *cos.Obj
return s.ObjectService.Get(ctx, name, opt, id...)
}

envelope := getEnvelopeFromHeader(&meta.Header)
envelope, err := getEnvelopeFromHeader(&meta.Header)
if err != nil {
return nil, err
}
if !envelope.IsValid() {
return nil, fmt.Errorf("get envelope from header failed, object:%v", name)
}
Expand Down Expand Up @@ -208,20 +212,39 @@ func addCryptoHeaders(header *http.Header, cd *CipherData) {
if cd.MatDesc != "" {
header.Add(COSClientSideEncryptionMatDesc, cd.MatDesc)
}
header.Add(COSClientSideEncryptionKey, string(cd.EncryptedKey))
header.Add(COSClientSideEncryptionStart, string(cd.EncryptedIV))
// encrypted key
strEncryptedKey := base64.StdEncoding.EncodeToString(cd.EncryptedKey)
header.Add(COSClientSideEncryptionKey, strEncryptedKey)

// encrypted iv
strEncryptedIV := base64.StdEncoding.EncodeToString(cd.EncryptedIV)
header.Add(COSClientSideEncryptionStart, strEncryptedIV)

header.Add(COSClientSideEncryptionWrapAlg, cd.WrapAlgorithm)
header.Add(COSClientSideEncryptionCekAlg, cd.CEKAlgorithm)
}

func getEnvelopeFromHeader(header *http.Header) Envelope {
func getEnvelopeFromHeader(header *http.Header) (Envelope, error) {
var envelope Envelope

envelope.CipherKey = header.Get(COSClientSideEncryptionKey)
decodedKey, err := base64.StdEncoding.DecodeString(envelope.CipherKey)
if err != nil {
return envelope, err
}
envelope.CipherKey = string(decodedKey)

envelope.IV = header.Get(COSClientSideEncryptionStart)
decodedIV, err := base64.StdEncoding.DecodeString(envelope.IV)
if err != nil {
return envelope, err
}
envelope.IV = string(decodedIV)

envelope.MatDesc = header.Get(COSClientSideEncryptionMatDesc)
envelope.WrapAlg = header.Get(COSClientSideEncryptionWrapAlg)
envelope.CEKAlg = header.Get(COSClientSideEncryptionCekAlg)
return envelope
return envelope, nil
}

func isEncrypted(header *http.Header) bool {
Expand Down
8 changes: 6 additions & 2 deletions crypto/crypto_object_part_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ func (s *CosTestSuite) TestMultiUpload_DecryptWithKey() {
resp, err = s.CClient.Object.Head(context.Background(), name, nil)
assert.Nil(s.T(), err, "HeadObject Failed")
cipherKey := resp.Header.Get(coscrypto.COSClientSideEncryptionKey)
cipherKeybs, err := base64.StdEncoding.DecodeString(cipherKey)
assert.Nil(s.T(), err, "base64 Decode Failed")
cipherIV := resp.Header.Get(coscrypto.COSClientSideEncryptionStart)
key, err := s.Master.Decrypt([]byte(cipherKey))
cipherIVbs, err := base64.StdEncoding.DecodeString(cipherIV)
assert.Nil(s.T(), err, "base64 Decode Failed")
key, err := s.Master.Decrypt(cipherKeybs)
assert.Nil(s.T(), err, "Master Decrypt Failed")
iv, err := s.Master.Decrypt([]byte(cipherIV))
iv, err := s.Master.Decrypt(cipherIVbs)
assert.Nil(s.T(), err, "Master Decrypt Failed")

// 手动解密
Expand Down
8 changes: 6 additions & 2 deletions crypto/crypto_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,14 @@ func (s *CosTestSuite) TestPutGetDeleteObject_DecryptWithKey_10MB() {
resp, err := s.CClient.Object.Head(context.Background(), name, nil)
assert.Nil(s.T(), err, "HeadObject Failed")
cipherKey := resp.Header.Get(coscrypto.COSClientSideEncryptionKey)
cipherKeybs, err := base64.StdEncoding.DecodeString(cipherKey)
assert.Nil(s.T(), err, "base64 Decode Failed")
cipherIV := resp.Header.Get(coscrypto.COSClientSideEncryptionStart)
key, err := s.Master.Decrypt([]byte(cipherKey))
cipherIVbs, err := base64.StdEncoding.DecodeString(cipherIV)
assert.Nil(s.T(), err, "base64 Decode Failed")
key, err := s.Master.Decrypt(cipherKeybs)
assert.Nil(s.T(), err, "Master Decrypt Failed")
iv, err := s.Master.Decrypt([]byte(cipherIV))
iv, err := s.Master.Decrypt(cipherIVbs)
assert.Nil(s.T(), err, "Master Decrypt Failed")

// 正常读取
Expand Down
1 change: 1 addition & 0 deletions crypto/master_kms_cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func (kc *MasterKMSCipher) Encrypt(plaintext []byte) ([]byte, error) {
if err != nil {
return nil, err
}
// https://cloud.tencent.com/document/product/573/34420 文档有误,返回的结果并没有base64编码
return []byte(*resp.Response.CiphertextBlob), nil
}

Expand Down
11 changes: 9 additions & 2 deletions example/crypto/crypto_sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ func log_status(err error) {
os.Exit(1)
}

func cos_max(x, y int64) int64 {
if x > y {
return x
}
return y
}

func simple_put_object() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
Expand Down Expand Up @@ -196,7 +203,7 @@ func multi_put_object() {
cryptoCtx := coscrypto.CryptoContext{
DataSize: contentLength,
// 每个分块需要16字节对齐
PartSize: (contentLength / 16 / 3) * 16,
PartSize: cos_max(1024*1024, (contentLength/16/3)*16),
}
v, _, err := client.Object.InitiateMultipartUpload(context.Background(), name, nil, &cryptoCtx)
log_status(err)
Expand Down Expand Up @@ -268,7 +275,7 @@ func multi_put_object_from_file() {
cryptoCtx := coscrypto.CryptoContext{
DataSize: contentLength,
// 每个分块需要16字节对齐
PartSize: (contentLength / 16 / 3) * 16,
PartSize: cos_max(1024*1024, (contentLength/16/3)*16),
}
// 切分数据
_, chunks, _, err := cos.SplitFileIntoChunks(filepath, cryptoCtx.PartSize)
Expand Down
6 changes: 6 additions & 0 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,9 @@ func SplitFileIntoChunks(filePath string, partSize int64) (int64, []Chunk, int,
}
var partNum int64
if partSize > 0 {
if partSize < 1024*1024 {
return 0, nil, 0, errors.New("partSize>=1048576 is required")
}
partNum = stat.Size() / partSize
if partNum >= 10000 {
return 0, nil, 0, errors.New("Too many parts, out of 10000")
Expand Down Expand Up @@ -1066,6 +1069,9 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string
func SplitSizeIntoChunks(totalBytes int64, partSize int64) ([]Chunk, int, error) {
var partNum int64
if partSize > 0 {
if partSize < 1024*1024 {
return nil, 0, errors.New("partSize>=1048576 is required")
}
partNum = totalBytes / partSize
if partNum >= 10000 {
return nil, 0, errors.New("Too manry parts, out of 10000")
Expand Down

0 comments on commit 05379cf

Please sign in to comment.