Data protection includes protecting data while in transit (as it travels to and from the server) and at rest (while it is stored on disk). You can do the following to protect your data when using storage services:
- Secure Socket Layer/Transport Layer Security (SSL/TLS): Protect data in transit.
- Client-Side Encryption: You manage the encryption keys, encryption process, and related tools all yourself. This can protect data both in transit and at rest, and this is transparent to the server.
- Server-Side Encryption: Request the server to encrypt your data before it is persisted to disk.
Recently, we implemented SSE support in go-storage, and let's talk about Server-Side Encryption (shorten to SSE) here.
What is SSE
Generally, the server will use AES-256, a symmetric-key algorithm, to encrypt your data. (Exceptionally, Aliyun Object Storage supports SM-4.) AES-256 uses a 32-byte binary key, and the same key is used in encryption and decryption. You have three mutually exclusive options, depending on how you choose to manage the encryption keys.
- SSE with Keys Managed by Cloud Service Provider
- SSE with Customer Master Keys (CMKs) Stored in Key Management Service, often called SSE-KMS
- SSE with Customer-Provided Keys, often called SSE-C
Note: not all service providers provide all of the above.
SSE with Keys Managed by Cloud Service Provider
In this way, the server will manage the keys, and the encryption is transparent to you. Some service providers (e.g., Google Cloud Storage and Azure) set this as default behavior and require no setup or configuration (and no extra charge), so your data is protected silently at rest by SSE! The others require you to request SSE explicitly at the time of object creation by adding a header, or configure a bucket-level policy. Generally, reading an encrypted object requires no special configuration.
SSE with Customer Master Keys (CMKs) Stored in Key Management Service (SSE-KMS)
In this way, you ask the service provider's Key Management Service to generate and store CMKs which can be managed by you (e.g., establishing and maintaining their key policies, enabling and disabling them). Then you can request SSE with the CMK (by specifying its key-id in the header) at the time of object creation, or configure a bucket-level policy. When reading an encrypted object, the client doesn't need to give the key-id, but must have access to the CMK.
SSE with Customer-Provided Keys (SSE-C)
In this way, you create and store encryption keys yourself. Different from Client-Side Encryption, in SSE-C you send unencrypted data along with the encryption key to the server, and then the server uses the key to encrypt your data, but doesn't store the key. When reading an encrypted object, you will have to carry the encryption key again to let the server decrypt your data with the key. In other words, you manage the encryption keys, and the server manages the encryption process and related tools.
How to Use SSE in go-storage
Since different services support different SSE options and have different behaviors, SSE-related pairs are considered service pairs. So you will have to check which options are provided for your specific service first. We listed supported options and related pairs in our service docs. You'd better first choose the SSE option you want to use, and then ignore other pairs in case of being confused with the usage of the pairs.
We recommend using SSE with DefaultPairs, where you only provide SSE-related options during
NewStorager and can write the same logic for different services. Take s3 for example. The code snippets come from go-storage-example