LapTrinhBlockchain

Chia sẻ kiến thức về Lập Trình Blockchain

Kiến thức phần mềm, Lập trình NodeJs, Nâng cao Kiến thức

Quản lý khóa mã hóa bằng AWS KMS trong Node.js

Quản lý khóa mã hóa bằng AWS KMS trong Node.js

Quản lý khóa mã hóa bằng AWS KMS trong Node.js

Chia sẻ bài viết
5
(68)

Bảo mật rất quan trọng khi phát triển ứng dụng. Làm cách nào để mã hóa dữ liệu và quản lý khóa mã hóa trong ứng dụng của bạn? Quản lý khóa thành công là rất quan trọng đối với tính bảo mật của hệ thống mật mã. Đây là lúc KMS phát huy tác dụng. Đầu tiên chúng ta hãy xem KMS thực sự là gì.

Hệ thống quản lý khóa (KMS – Key management system)

Theo Wikipedia, Hệ thống quản lý khóa (KMS – Key management system), còn được gọi là hệ thống quản lý khóa mật mã (CKMS – Crytographic key management system), là một phương pháp tích hợp để tạo, phân phối và quản lý khóa mật mã cho các thiết bị và ứng dụng.

So với thuật ngữ quản lý khóa, KMS được điều chỉnh cho phù hợp với các trường hợp sử dụng cụ thể như cập nhật phần mềm bảo mật hoặc giao tiếp giữa các máy. Theo cách tiếp cận toàn diện, nó bao gồm tất cả các khía cạnh bảo mật — từ việc tạo khóa an toàn cho đến trao đổi khóa an toàn cho đến xử lý và lưu trữ khóa an toàn trên máy khách. Do đó, KMS bao gồm chức năng phụ trợ để tạo, phân phối và thay thế khóa cũng như chức năng máy khách để chèn khóa, lưu trữ và quản lý khóa trên thiết bị. Với Internet of Things, KMS trở thành một phần quan trọng để bảo mật các thiết bị được kết nối.

KMS giúp cuộc sống của bạn trở nên dễ dàng khi xử lý việc quản lý khóa và mã hóa.

AWS KMS

AWS KMS là một dịch vụ của AWS giúp bạn dễ dàng quản lý khóa mã hóa của mình. Nó sử dụng Mô-đun bảo mật phần cứng (HSM – Hardware Security Module) trong phần phụ trợ. AWS KMS được tích hợp với các dịch vụ AWS khác. Nó cũng có chi phí thấp.

AWS KMS cung cấp khả năng kiểm soát quyền truy cập vào khóa của bạn để bạn có thể xác định ai có thể truy cập vào khóa khi nào có thể truy cập vào khóa và nhiều tùy chọn khác.

AWS KMS hỗ trợ nhiều thuật toán khác nhau. Bạn có thể xem giá AWS KMS tại đây. Bậc miễn phí bao gồm 20.000 yêu cầu/tháng.

Sử dụng AWS KMS với Node.js

B1: Tạo CMK (Customer managed key)

Vào dịch vụ KMS trên AWS, trên giao diện chúng ta kích nút “Create a key“.

Các bước tạo CMK (Customer managed key)

Trên giao diện tùy theo mục đích mà lựa chọn tham số cho hợp lý, tôi chọn như dưới và sau đó nhấn Next:

  • Key type: Asymmetric
  • Key usage: Encrypt and decrypt
  • Key spec: RSA_2048
  • Key material origin: KMS
  • Regionality: Single-Region key
Các bước tạo CMK (Customer managed key)

Tiếp theo bạn nhập Alias, rồi nhấn Next:

Các bước tạo CMK (Customer managed key)

Đoạn “Define key administrative permisions không chọn gì rồi nhấn Next:

Các bước tạo CMK (Customer managed key)

Tiếp đến “Define key usage permissions“, không cần chọn gì rồi nhấn Next:

Các bước tạo CMK (Customer managed key)

Đến bước Review để mặc định rồi nhấn Finish để hoàn thành:

Các bước tạo CMK (Customer managed key)

Sau khi tạo xong bạn sẽ thấy có ARN, nhưng ID tương ứng với key vừa tạo (Gọi Key-ARN):

B2: Tạo user có quyền truy cập vào CMK vừa tạo ở trên và cấu hình chặn theo IP

Chúng ta vào dịch vụ AIM của AWS, vào phần Users, sau đó nhấn nút “Create user” với thông tin:

  • User name: kms-test-user
  • Provide user access to the AWS Management Console: Not check
  • Permissions options: Chọn Attach policies directly, sau đó chọn Policy name là “ROSAKMSProviderPolicy
  • Use a permissions boundary to control the maximum permissions: Not check

Sau khi tạo user xong, chúng ta vào kích vào User để thực hiện cập nhật thông tin:

  • Kích link “Create access key” để tạo access key, key này dùng để kết nối từ ứng dụng. Sau khi tạo ta được “AWS Access Key ID” và “AWS Secret Access Key“.
  • Trong tab “Permissions“, kích nút “Add permissions -> Create inline Policy“, chọn phần JSON và nhập thông tin như dưới.

Đây là nội dung của Policy, bạn nhớ thay Key-ARN cho đúng. Trong Policy này tôi cấu hình chỉ cho IP 171.241.18.145 có thể kết nối được, bạn có thể đổi IP khác hoặc xóa thuộc tính Condition nếu không muốn chặn theo IP:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:DescribeKey",
                "kms:ListResourceTags"
            ],
            "Resource": "<Key-ARN>",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "171.241.18.145/32"
                    ]
                }
            }
        }
    ]
}
Cấu hình Policy và chặn theo IP

B3: Cấu hình AWS KMS cho Client

Trước khi có thể dùng code, chúng ta cần phải cấu hình AWS KMS cho Client. Để làm được việc này chúng ta cần cài đặt awscli:

# Cài đặt awscli
sudo apt  install awscli

# Cập nhật thư viện python3 cho awscli
pip3 install --upgrade awscli

# Xem cú pháp lệnh
aws kms help
aws kms encrypt help
aws kms decrypt help

Sau khi cài đặt xong, chúng ta đánh lệnh sau, sau đó bạn nhập Region, AWS Access Key IDAWS Secret Access Key:

aws configure
------------------------------
AWS Access Key ID [None]: xxxxxxxxxxxxxx
AWS Secret Access Key [None]: yyyyyyyyyyyyy
Default region name [None]: us-east-1
Default output format [NONE]:

Bây giờ chúng ta thử sử dụng awscli để thực hiện mã hóa và giải mã:

# Thực hiện mã hóa
aws kms encrypt --key-id <Key-ARN> --encryption-algorithm RSAES_OAEP_SHA_256 --plaintext "Testing!"
------------------
{
    "CiphertextBlob": "OhneGN0R3yRBKrP1Y9F3mmCtgDGyFaYwZwzwvBNKWOKlZ6g82KSrZOJW5dRWaps26ozexxG3VxO1ULxahfSfFh+8cWvmJuYYv8opC8xNxiY3bh2f8Pz/2SQEgqN+fujAX1v27+3nRsxdB6kJWwFWXFpDDihBOeLafBsoQVq0eJrFyoApdmcXstzh1xQQ3iAr2/jIjxYMmgtmk66uD7VTnWTBNrw8cPn+1CRM8kGws97WgxIGWmZP85qPvTUYSNSnmeOTqzjdRCcP/zcguWmIbAom7R2fi1V8B7i2pIID3NNKgKAzwkv8WdyFxkc7tVRI4+iBfs0M4VqdP5HlZgLR+A==",
    "KeyId": "arn:aws:kms:us-east-1:496179413494:key/b5af7531-251b-4dd0-b28a-2b1188e47d4d",
    "EncryptionAlgorithm": "RSAES_OAEP_SHA_256"
}

# Thực hiện giải mã
aws kms decrypt --key-id <Key-ARN> --encryption-algorithm RSAES_OAEP_SHA_256 --ciphertext-blob fileb://<(echo 'OhneGN0R3yRBKrP1Y9F3mmCtgDGyFaYwZwzwvBNKWOKlZ6g82KSrZOJW5dRWaps26ozexxG3VxO1ULxahfSfFh+8cWvmJuYYv8opC8xNxiY3bh2f8Pz/2SQEgqN+fujAX1v27+3nRsxdB6kJWwFWXFpDDihBOeLafBsoQVq0eJrFyoApdmcXstzh1xQQ3iAr2/jIjxYMmgtmk66uD7VTnWTBNrw8cPn+1CRM8kGws97WgxIGWmZP85qPvTUYSNSnmeOTqzjdRCcP/zcguWmIbAom7R2fi1V8B7i2pIID3NNKgKAzwkv8WdyFxkc7tVRI4+iBfs0M4VqdP5HlZgLR+A==' | base64 -d)

# Thực hiện giải mã và lấy ra đúng text ban đầu
aws kms decrypt --key-id <Key-ARN> --encryption-algorithm RSAES_OAEP_SHA_256 --ciphertext-blob fileb://<(echo 'OhneGN0R3yRBKrP1Y9F3mmCtgDGyFaYwZwzwvBNKWOKlZ6g82KSrZOJW5dRWaps26ozexxG3VxO1ULxahfSfFh+8cWvmJuYYv8opC8xNxiY3bh2f8Pz/2SQEgqN+fujAX1v27+3nRsxdB6kJWwFWXFpDDihBOeLafBsoQVq0eJrFyoApdmcXstzh1xQQ3iAr2/jIjxYMmgtmk66uD7VTnWTBNrw8cPn+1CRM8kGws97WgxIGWmZP85qPvTUYSNSnmeOTqzjdRCcP/zcguWmIbAom7R2fi1V8B7i2pIID3NNKgKAzwkv8WdyFxkc7tVRI4+iBfs0M4VqdP5HlZgLR+A==' | base64 -d) --query Plaintext --output text | base64 -d

B4: Sử dụng NodeJs để thực hiện mã hóa và giải mã

Chúng ta viết code NodeJs như sau trong tệp main.js:

require('dotenv').config();
const KMS = require('@aws-sdk/client-kms').KMS;

const KmsKeyId = process.env.KMS_KEY_ID;
let kmsClient = null;

function getKmsClient() {
    if (!kmsClient) {
        kmsClient = new KMS({
            region: 'us-east-1'
        });
    }
    return kmsClient;
}

async function encryptData(data) {
    let kmsClient = getKmsClient();
    let cipherData = await kmsClient.encrypt({
        KeyId: KmsKeyId,
        Plaintext: Buffer.from(data, 'utf-8'),
        EncryptionAlgorithm: "RSAES_OAEP_SHA_256"
    });
    // console.log("CipherData", cipherData);
    let cipherText =  Buffer.from(cipherData.CiphertextBlob).toString('base64');
    console.log("CipherText", cipherText);
    return cipherText;
}

async function decryptData(cipherText) {
    let kmsClient = getKmsClient();
    let rawData = await kmsClient.decrypt({
        KeyId: KmsKeyId,
        CiphertextBlob: Buffer.from(cipherText, 'base64'),
        EncryptionAlgorithm: "RSAES_OAEP_SHA_256"
    });
    // console.log("RawData", rawData);
    let rawText =  Buffer.from(rawData.Plaintext, "utf-8").toString();
    console.log("RawText", rawText);
    return rawText;
}

async function main() {
    console.log("-----------------------------------");
    let originText = "This is only testing data!!!";
    console.log("OriginText", originText);
    console.log("-----------------------------------");
    let cipherText = await encryptData(originText);
    console.log("-----------------------------------");
    await decryptData(cipherText);
    console.log("-----------------------------------");
}
main();

Để chạy được code trên ta thực hiện:

# Cài đặt thư viện client-kms trên NodeJs
npm i @aws-sdk/client-kms

# Tạo tệp .env và cấu hình cho key KMS_KEY_ID

# Chạy ví dụ
node main.js

Trong phần này tôi sẽ chia sẻ cách sử dụng AWS KMS trong ứng dụng Node.js của bạn. Tôi sẽ đề cập đến các chủ đề sau ở đây:

Một số lỗi liên quan và cách xử lý

Lỗi: ImportError: cannot import name ‘docevents’

Lỗi này liên quan tới thư viện của Python, ta fix lỗi bằng lệnh dưới:

pip3 install --upgrade awscli

Lỗi: Unable to locate credentials. You can configure credentials by running “aws configure”.

Lỗi này là do bạn chưa cấu hình “AWS Access Key ID” và “AWS Secret Access Key“. Cần đánh lệnh sau để cấu hình:

aws configure

Lỗi: An error occurred (AccessDeniedException) when calling the Encrypt operation

Khi bạn chạy lệnh “aws kms encrypt” thấy lỗi phát sinh:

An error occurred (AccessDeniedException) when calling the Encrypt operation: User: <User> is not authorized to perform: kms:Encrypt on resource: <> because no identity-based policy allows the kms:Encrypt action

Fix lỗi bằng cách sửa lại Policy với quyền rõ ràng trên resource trên.

Lỗi: An error occurred (InvalidKeyUsageException) when calling the Encrypt operation

Khi thực hiện “aws kms encrypt” báo lỗi:

An error occurred (InvalidKeyUsageException) when calling the Encrypt operation: Algorithm SYMMETRIC_DEFAULT is incompatible with key spec RSA_2048

Để fix lỗi này phải thêm tham số “–encryption-algorithm RSAES_OAEP_SHA_256“.

Nguồn: Tổng hợp

Bài viết này có hữu ích với bạn?

Kích vào một biểu tượng ngôi sao để đánh giá bài viết!

Xếp hạng trung bình 5 / 5. Số phiếu: 68

Bài viết chưa có đánh giá! Hãy là người đầu tiên đánh giá bài viết này.

Trả lời

Giao diện bởi Anders Norén