sample_crypto.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. kms "github.com/aliyun/alibaba-cloud-sdk-go/services/kms"
  8. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  9. "github.com/aliyun/aliyun-oss-go-sdk/oss/crypto"
  10. )
  11. func SampleRsaNormalObject() {
  12. // create oss client
  13. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  14. if err != nil {
  15. fmt.Println("Error:", err)
  16. os.Exit(-1)
  17. }
  18. // Create a description of the master key. Once created, it cannot be modified. The master key description and the master key are one-to-one correspondence.
  19. // If all objects use the same master key, the master key description can also be empty, but subsequent replacement of the master key is not supported.
  20. // Because if the description is empty, it is impossible to determine which master key is used when decrypting object.
  21. // It is strongly recommended that: configure the master key description(json string) for each master key, and the client should save the correspondence between them.
  22. // The server does not save their correspondence
  23. // Map converted by the master key description information (json string)
  24. materialDesc := make(map[string]string)
  25. materialDesc["desc"] = "<your master encrypt key material describe information>"
  26. // Create a master key object based on the master key description
  27. masterRsaCipher, err := osscrypto.CreateMasterRsa(materialDesc, "<your rsa public key>", "<your rsa private key>")
  28. if err != nil {
  29. fmt.Println("Error:", err)
  30. os.Exit(-1)
  31. }
  32. // Create an interface for encryption based on the master key object, encrypt using aec ctr mode
  33. contentProvider := osscrypto.CreateAesCtrCipher(masterRsaCipher)
  34. // Get a storage space for client encryption, the bucket has to be created
  35. // Client-side encrypted buckets have similar usages to ordinary buckets.
  36. cryptoBucket, err := osscrypto.GetCryptoBucket(client, "<yourBucketName>", contentProvider)
  37. if err != nil {
  38. fmt.Println("Error:", err)
  39. os.Exit(-1)
  40. }
  41. // put object ,will be automatically encrypted
  42. err = cryptoBucket.PutObject("<yourObjectName>", bytes.NewReader([]byte("yourObjectValueByteArrary")))
  43. if err != nil {
  44. fmt.Println("Error:", err)
  45. os.Exit(-1)
  46. }
  47. // get object ,will be automatically decrypted
  48. body, err := cryptoBucket.GetObject("<yourObjectName>")
  49. if err != nil {
  50. fmt.Println("Error:", err)
  51. os.Exit(-1)
  52. }
  53. defer body.Close()
  54. data, err := ioutil.ReadAll(body)
  55. if err != nil {
  56. fmt.Println("Error:", err)
  57. os.Exit(-1)
  58. }
  59. fmt.Println("data:", string(data))
  60. }
  61. func SampleRsaMultiPartObject() {
  62. // create oss client
  63. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  64. if err != nil {
  65. fmt.Println("Error:", err)
  66. os.Exit(-1)
  67. }
  68. // Create a description of the master key. Once created, it cannot be modified. The master key description and the master key are one-to-one correspondence.
  69. // If all objects use the same master key, the master key description can also be empty, but subsequent replacement of the master key is not supported.
  70. // Because if the description is empty, it is impossible to determine which master key is used when decrypting object.
  71. // It is strongly recommended that: configure the master key description(json string) for each master key, and the client should save the correspondence between them.
  72. // The server does not save their correspondence
  73. // Map converted by the master key description information (json string)
  74. materialDesc := make(map[string]string)
  75. materialDesc["desc"] = "<your master encrypt key material describe information>"
  76. // Create a master key object based on the master key description
  77. masterRsaCipher, err := osscrypto.CreateMasterRsa(materialDesc, "<your rsa public key>", "<your rsa private key>")
  78. if err != nil {
  79. fmt.Println("Error:", err)
  80. os.Exit(-1)
  81. }
  82. // Create an interface for encryption based on the master key object, encrypt using aec ctr mode
  83. contentProvider := osscrypto.CreateAesCtrCipher(masterRsaCipher)
  84. // Get a storage space for client encryption, the bucket has to be created
  85. // Client-side encrypted buckets have similar usages to ordinary buckets.
  86. cryptoBucket, err := osscrypto.GetCryptoBucket(client, "<yourBucketName>", contentProvider)
  87. if err != nil {
  88. fmt.Println("Error:", err)
  89. os.Exit(-1)
  90. }
  91. fileName := "<yourLocalFilePath>"
  92. fileInfo, err := os.Stat(fileName)
  93. if err != nil {
  94. fmt.Println("Error:", err)
  95. os.Exit(-1)
  96. }
  97. fileSize := fileInfo.Size()
  98. // Encryption context information
  99. var cryptoContext osscrypto.PartCryptoContext
  100. cryptoContext.DataSize = fileSize
  101. // The expected number of parts, the actual number of parts is subject to subsequent calculations.
  102. expectPartCount := int64(10)
  103. //Currently aes ctr encryption block size requires 16 byte alignment
  104. cryptoContext.PartSize = (fileSize / expectPartCount / 16) * 16
  105. imur, err := cryptoBucket.InitiateMultipartUpload("<yourObjectName>", &cryptoContext)
  106. if err != nil {
  107. fmt.Println("Error:", err)
  108. os.Exit(-1)
  109. }
  110. chunks, err := oss.SplitFileByPartSize(fileName, cryptoContext.PartSize)
  111. if err != nil {
  112. fmt.Println("Error:", err)
  113. os.Exit(-1)
  114. }
  115. var partsUpload []oss.UploadPart
  116. for _, chunk := range chunks {
  117. part, err := cryptoBucket.UploadPartFromFile(imur, fileName, chunk.Offset, chunk.Size, (int)(chunk.Number), cryptoContext)
  118. if err != nil {
  119. fmt.Println("Error:", err)
  120. os.Exit(-1)
  121. }
  122. partsUpload = append(partsUpload, part)
  123. }
  124. // Complete
  125. _, err = cryptoBucket.CompleteMultipartUpload(imur, partsUpload)
  126. if err != nil {
  127. fmt.Println("Error:", err)
  128. os.Exit(-1)
  129. }
  130. }
  131. // Query the master key according to the master key description information.
  132. // If you need to decrypt different master key encryption objects, you need to provide this interface.
  133. type MockRsaManager struct {
  134. }
  135. func (mg *MockRsaManager) GetMasterKey(matDesc map[string]string) ([]string, error) {
  136. // to do
  137. keyList := []string{"<yourRsaPublicKey>", "<yourRsaPrivatKey>"}
  138. return keyList, nil
  139. }
  140. // Decrypt the object encrypted by different master keys
  141. func SampleMultipleMasterRsa() {
  142. // create oss client
  143. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  144. if err != nil {
  145. fmt.Println("Error:", err)
  146. os.Exit(-1)
  147. }
  148. // Create a description of the master key. Once created, it cannot be modified. The master key description and the master key are one-to-one correspondence.
  149. // If all objects use the same master key, the master key description can also be empty, but subsequent replacement of the master key is not supported.
  150. // Because if the description is empty, it is impossible to determine which master key is used when decrypting object.
  151. // It is strongly recommended that: configure the master key description(json string) for each master key, and the client should save the correspondence between them.
  152. // The server does not save their correspondence
  153. // Map converted by the master key description information (json string)
  154. materialDesc := make(map[string]string)
  155. materialDesc["desc"] = "<your master encrypt key material describe information>"
  156. // Create a master key object based on the master key description
  157. masterRsaCipher, err := osscrypto.CreateMasterRsa(materialDesc, "<your rsa public key>", "<your rsa private key>")
  158. if err != nil {
  159. fmt.Println("Error:", err)
  160. os.Exit(-1)
  161. }
  162. // Create an interface for encryption based on the master key object, encrypt using aec ctr mode
  163. contentProvider := osscrypto.CreateAesCtrCipher(masterRsaCipher)
  164. // If you need to decrypt objects encrypted by different ma keys, you need to provide this interface.
  165. var mockRsaManager MockRsaManager
  166. var options []osscrypto.CryptoBucketOption
  167. options = append(options, osscrypto.SetMasterCipherManager(&mockRsaManager))
  168. // Get a storage space for client encryption, the bucket has to be created
  169. // Client-side encrypted buckets have similar usages to ordinary buckets.
  170. cryptoBucket, err := osscrypto.GetCryptoBucket(client, "<yourBucketName>", contentProvider, options...)
  171. if err != nil {
  172. fmt.Println("Error:", err)
  173. os.Exit(-1)
  174. }
  175. // put object ,will be automatically encrypted
  176. err = cryptoBucket.PutObject("<yourObjectName>", bytes.NewReader([]byte("yourObjectValueByteArrary")))
  177. if err != nil {
  178. fmt.Println("Error:", err)
  179. os.Exit(-1)
  180. }
  181. // get object ,will be automatically decrypted
  182. body, err := cryptoBucket.GetObject("<otherObjectNameEncryptedWithOtherRsa>")
  183. if err != nil {
  184. fmt.Println("Error:", err)
  185. os.Exit(-1)
  186. }
  187. defer body.Close()
  188. data, err := ioutil.ReadAll(body)
  189. if err != nil {
  190. fmt.Println("Error:", err)
  191. os.Exit(-1)
  192. }
  193. fmt.Println("data:", string(data))
  194. }
  195. func SampleKmsNormalObject() {
  196. // create oss client
  197. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  198. if err != nil {
  199. fmt.Println("Error:", err)
  200. os.Exit(-1)
  201. }
  202. // create kms client
  203. kmsClient, err := kms.NewClientWithAccessKey("<yourKmsRegion>", "<yourKmsAccessKeyId>", "<yourKmsAccessKeySecret>")
  204. if err != nil {
  205. fmt.Println("Error:", err)
  206. os.Exit(-1)
  207. }
  208. // Create a description of the master key. Once created, it cannot be modified. The master key description and the master key are one-to-one correspondence.
  209. // If all objects use the same master key, the master key description can also be empty, but subsequent replacement of the master key is not supported.
  210. // Because if the description is empty, it is impossible to determine which master key is used when decrypting object.
  211. // It is strongly recommended that: configure the master key description(json string) for each master key, and the client should save the correspondence between them.
  212. // The server does not save their correspondence
  213. // Map converted by the master key description information (json string)
  214. materialDesc := make(map[string]string)
  215. materialDesc["desc"] = "<your kms encrypt key material describe information>"
  216. // Create a master key object based on the master key description
  217. masterkmsCipher, err := osscrypto.CreateMasterAliKms(materialDesc, "<YourKmsId>", kmsClient)
  218. if err != nil {
  219. fmt.Println("Error:", err)
  220. os.Exit(-1)
  221. }
  222. // Create an interface for encryption based on the master key object, encrypt using aec ctr mode
  223. contentProvider := osscrypto.CreateAesCtrCipher(masterkmsCipher)
  224. // Get a storage space for client encryption, the bucket has to be created
  225. // Client-side encrypted buckets have similar usages to ordinary buckets.
  226. cryptoBucket, err := osscrypto.GetCryptoBucket(client, "<yourBucketName>", contentProvider)
  227. if err != nil {
  228. fmt.Println("Error:", err)
  229. os.Exit(-1)
  230. }
  231. // put object ,will be automatically encrypted
  232. err = cryptoBucket.PutObject("<yourObjectName>", bytes.NewReader([]byte("yourObjectValueByteArrary")))
  233. if err != nil {
  234. fmt.Println("Error:", err)
  235. os.Exit(-1)
  236. }
  237. // get object ,will be automatically decrypted
  238. body, err := cryptoBucket.GetObject("<yourObjectName>")
  239. if err != nil {
  240. fmt.Println("Error:", err)
  241. os.Exit(-1)
  242. }
  243. defer body.Close()
  244. data, err := ioutil.ReadAll(body)
  245. if err != nil {
  246. fmt.Println("Error:", err)
  247. os.Exit(-1)
  248. }
  249. fmt.Println("data:", string(data))
  250. }
  251. func main() {
  252. SampleRsaNormalObject()
  253. SampleRsaMultiPartObject()
  254. SampleMultipleMasterRsa()
  255. SampleKmsNormalObject()
  256. }