วิธีทำธุรกรรมเนื้อหาดิจิทัลด้วยการประมวลผลจากหลายฝ่ายและพื้นที่ลับ

วิธีทำธุรกรรมกับเนื้อหาดิจิทัลด้วยการคำนวณแบบหลายฝ่ายและพื้นที่ส่วนบุคคล

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ ม.ค. 9, 2025
account_circleเขียนโดย Devon Yarbrough, Bertrand Portier, Chris Diya, Meetrajsinh Vala

1 ภาพรวม

ก่อนจะเริ่มต้น แม้ว่าจะไม่ใช่สิ่งจําเป็นทั้งหมด แต่ความรู้เกี่ยวกับฟีเจอร์และแนวคิดต่อไปนี้จะเป็นประโยชน์ในโค้ดแล็บนี้

4670cd5427aa39a6.png

สิ่งที่คุณจะได้เรียนรู้

ห้องทดลองนี้แสดงการใช้งานอ้างอิงสำหรับการลงนามบล็อกเชนที่เป็นไปตามข้อกำหนด MPC โดยใช้พื้นที่ส่วนบุคคล เราจะอธิบายแนวคิดนี้โดยใช้สถานการณ์สมมติที่บริษัท Primus ต้องการโอนเนื้อหาดิจิทัลไปยังบริษัท Secundus ในกรณีนี้ บริษัท Primus ใช้รูปแบบที่เป็นไปตาม MPC ซึ่งหมายความว่าจะใช้ส่วนแบ่งคีย์ที่กระจายแทนการใช้คีย์ส่วนตัวแต่ละรายการ บุคคลหลายฝ่ายจะถือครองส่วนแบ่งคีย์เหล่านี้ ซึ่งในกรณีนี้ได้แก่ ขวัญใจและบัญชา แนวทางนี้ให้ประโยชน์หลายประการแก่ Company Primus ซึ่งรวมถึงประสบการณ์การใช้งานที่ง่ายขึ้น ประสิทธิภาพการปฏิบัติงาน และการควบคุมคีย์ส่วนตัว

เราจะอธิบายแง่มุมพื้นฐานของกระบวนการนี้โดยละเอียด รวมถึงอธิบายการตั้งค่าทางเทคนิคและแนะนำขั้นตอนอนุมัติและการลงนามที่เริ่มต้นการโอนเนื้อหาดิจิทัลจากบริษัท Primus ไปยังบริษัท Secundus โปรดทราบว่า Bob และ Alice ซึ่งเป็นพนักงานของบริษัท Primus จะต้องอนุมัติธุรกรรม

แม้ว่าการใช้งานอ้างอิงนี้จะสาธิตการดำเนินการเกี่ยวกับลายเซ็น แต่ก็ไม่ได้ครอบคลุมทุกแง่มุมของการจัดการคีย์ MPC ตัวอย่างเช่น เราไม่พูดถึงการสร้างคีย์ นอกจากนี้ ยังมีแนวทางอื่นๆ ที่ใช้ร่วมกันได้ เช่น การใช้บริการที่ไม่ใช่ Google Cloud เพื่อสร้างลายเซ็นร่วม หรือให้ผู้ร่วมลงนามสร้างลายเซ็นบล็อกเชนในสภาพแวดล้อมของตนเอง ซึ่งเป็นสถาปัตยกรรมแบบกระจายอำนาจมากขึ้น เราหวังว่าห้องทดลองนี้จะสร้างแรงบันดาลใจให้ใช้แนวทางต่างๆ กับ MPC ใน Google Cloud

คุณจะต้องทำงานกับเวิร์กโหลดง่ายๆ ที่ลงนามในธุรกรรม Ethereum ในพื้นที่ทำงานที่เป็นความลับโดยใช้วัสดุคีย์ของผู้ร่วมลงนาม การรับรองธุรกรรม Ethereum คือกระบวนการที่ผู้ใช้สามารถให้สิทธิ์ธุรกรรมในบล็อกเชน Ethereum หากต้องการส่งธุรกรรม Ethereum คุณต้องลงนามด้วยคีย์ส่วนตัว ซึ่งจะพิสูจน์ว่าคุณเป็นเจ้าของบัญชีและได้รับอนุญาตให้ทำธุรกรรม ขั้นตอนการลงนามมีดังนี้

  1. ผู้ส่งจะสร้างออบเจ็กต์ธุรกรรมที่ระบุที่อยู่ผู้รับ จำนวน ETH ที่จะส่ง และข้อมูลอื่นๆ ที่เกี่ยวข้อง
  2. ระบบจะใช้คีย์ส่วนตัวของผู้ส่งเพื่อแฮชข้อมูลธุรกรรม
  3. จากนั้นจึงใช้คีย์ส่วนตัวลงนามแฮช
  4. ลายเซ็นจะแนบอยู่กับออบเจ็กต์ธุรกรรม
  5. ระบบจะออกอากาศธุรกรรมไปยังเครือข่าย Ethereum

เมื่อโหนดในเครือข่ายได้รับธุรกรรม โหนดจะยืนยันลายเซ็นเพื่อให้แน่ใจว่าธุรกรรมดังกล่าวลงนามโดยเจ้าของบัญชี หากลายเซ็นถูกต้อง โหนดจะเพิ่มธุรกรรมลงในบล็อกเชน

ในการเริ่มต้น คุณจะต้องกำหนดค่าทรัพยากร Cloud ที่จำเป็น จากนั้นคุณจะเรียกใช้เวิร์กโหลดในพื้นที่ทำงานที่ปลอดภัย โค้ดแล็บนี้จะแนะนำขั้นตอนระดับสูงต่อไปนี้

  • วิธีกำหนดค่าทรัพยากรในระบบคลาวด์ที่จำเป็นสำหรับเรียกใช้พื้นที่ทำงานที่มีข้อมูลลับ
  • วิธีให้สิทธิ์เข้าถึงทรัพยากรที่มีการป้องกันตามแอตทริบิวต์ของสิ่งต่อไปนี้
  • สิ่งที่ต้องระบุ: คอนเทนเนอร์ของภาระงาน
  • ตำแหน่ง: สภาพแวดล้อมของพื้นที่ทำงานที่เป็นความลับ (อิมเมจพื้นที่ทำงานที่เป็นความลับใน Confidential VM)
  • ผู้ใช้: บัญชีที่ใช้งานเวิร์กโหลด
  • วิธีเรียกใช้เวิร์กโหลดใน VM ที่เป็นความลับซึ่งใช้รูปภาพ VM ของพื้นที่ทำงานที่เป็นความลับ

API ที่จำเป็น

คุณต้องเปิดใช้ API ต่อไปนี้ในโปรเจ็กต์ที่ระบุจึงจะทําตามคู่มือนี้ได้

ชื่อ API

ชื่อ API

cloudkms.googleapis.com

Cloud KMS

compute.googleapis.com

Compute Engine

confidentialcomputing.googleapis.com

Confidential Computing

iamcredentials.googleapis.com

IAM

artifactregistry.googleapis.com

Artifact Registry

2 ตั้งค่าทรัพยากรระบบคลาวด์

ก่อนเริ่มต้น

  • โคลน ที่เก็บนี้โดยใช้คําสั่งด้านล่างเพื่อรับสคริปต์ที่จําเป็นซึ่งใช้ในโค้ดแล็บนี้
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • เปลี่ยนไดเรกทอรีของ Codelab นี้
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
  • ตรวจสอบว่าคุณได้ตั้งค่าตัวแปรสภาพแวดล้อมของโปรเจ็กต์ที่จําเป็นดังที่แสดงด้านล่าง ดูข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าโปรเจ็กต์ GCP ได้ที่ โค้ดแล็บนี้ โปรดดูรายละเอียดเกี่ยวกับวิธีเรียกข้อมูลรหัสโปรเจ็กต์และความแตกต่างระหว่างรหัสโปรเจ็กต์กับชื่อโปรเจ็กต์และหมายเลขโปรเจ็กต์ได้ที่นี่ .
export PRIMUS_PROJECT_ID=<GCP project id>
gcloud services enable \
   cloudapis.googleapis.com \
    cloudkms.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    iam.googleapis.com \
    confidentialcomputing.googleapis.com
  • หากต้องการตั้งค่าตัวแปรสําหรับชื่อทรัพยากร ให้ใช้คําสั่งต่อไปนี้ โปรดทราบว่าการดำเนินการนี้จะลบล้างชื่อทรัพยากรเฉพาะสำหรับโปรเจ็กต์ GCP ของบริษัท ก เช่น export PRIMUS_INPUT_STORAGE_BUCKET='primus-input-bucket'
  • คุณสามารถตั้งค่าตัวแปรต่อไปนี้สําหรับโปรเจ็กต์ GCP ในบริษัท ก

$PRIMUS_INPUT_STORAGE_BUCKET

ที่เก็บข้อมูลซึ่งจัดเก็บคีย์ที่เข้ารหัส

$PRIMUS_RESULT_STORAGE_BUCKET

ที่เก็บข้อมูลที่จัดเก็บผลลัพธ์ธุรกรรม MPC

$PRIMUS_KEY

คีย์ KMS ที่ใช้เข้ารหัสข้อมูลที่จัดเก็บไว้ใน $PRIMUS_INPUT_STORAGE_BUCKET สำหรับ Primus Bank

$PRIMUS_KEYRING

กระเป๋าสตางค์ KMS ที่จะใช้สําหรับสร้างคีย์การเข้ารหัส $PRIMUS_KEY สําหรับ Primus Bank

$PRIMUS_WIP_PROVIDER

ผู้ให้บริการพูล Workload Identity ซึ่งมีเงื่อนไขแอตทริบิวต์ที่จะใช้กับโทเค็นที่บริการเวิร์กโหลด MPC ลงนาม

$PRIMUS_SERVICEACCOUNT

บัญชีบริการที่ $PRIMUS_WORKLOAD_IDENTITY_POOL ใช้เข้าถึงทรัพยากรที่ได้รับการปกป้อง บัญชีบริการนี้จะมีสิทธิ์ดูคีย์ที่เข้ารหัสซึ่งจัดเก็บอยู่ในที่เก็บข้อมูล $PRIMUS_INPUT_STORAGE_BUCKET

$PRIMUS_ARTIFACT_REPOSITORY

ที่เก็บอาร์ติแฟกต์สำหรับจัดเก็บอิมเมจคอนเทนเนอร์ของภาระงาน

$WORKLOAD_SERVICEACCOUNT

บัญชีบริการที่มีสิทธิ์เข้าถึง VM ข้อมูลที่เป็นความลับซึ่งเรียกใช้ภาระงาน

$WORKLOAD_CONTAINER

คอนเทนเนอร์ Docker ที่เรียกใช้เวิร์กโหลด

$WORKLOAD_IMAGE_NAME

ชื่อของรูปภาพคอนเทนเนอร์ภาระงาน

$WORKLOAD_IMAGE_TAG

แท็กของอิมเมจคอนเทนเนอร์ของภาระงาน

  • เรียกใช้สคริปต์ต่อไปนี้เพื่อตั้งค่าชื่อตัวแปรที่เหลือเป็นค่าตามรหัสโปรเจ็กต์สำหรับชื่อทรัพยากร
source config_env.sh

ตั้งค่าทรัพยากรระบบคลาวด์

ในขั้นตอนนี้ คุณจะต้องตั้งค่าทรัพยากรระบบคลาวด์ที่จําเป็นสําหรับการคํานวณแบบหลายฝ่าย คุณจะใช้สําคัญส่วนตัว 0000000000000000000000000000000000000000000000000000000000000001 ต่อไปนี้ในชั้นเรียนนี้

ในสภาพแวดล้อมที่ใช้งานจริง คุณจะต้องสร้างคีย์ส่วนตัวของคุณเอง อย่างไรก็ตาม เราจะแบ่งคีย์ส่วนตัวนี้ออกเป็น 2 ส่วนและเข้ารหัสแต่ละส่วนเพื่อวัตถุประสงค์ของห้องทดลองนี้ ในสถานการณ์ที่ใช้งานจริง คุณไม่ควรจัดเก็บคีย์ไว้ในไฟล์ข้อความธรรมดา แต่ให้สร้างคีย์ส่วนตัวนอก Google Cloud (หรือข้ามการสร้างคีย์ MPC ที่กำหนดเองไปเลย) แล้วเข้ารหัสเพื่อให้ไม่มีใครเข้าถึงคีย์ส่วนตัวหรือส่วนแบ่งคีย์ได้ เราจะใช้ Gcloud CLI ในการทดสอบนี้

เรียกใช้สคริปต์ต่อไปนี้เพื่อตั้งค่าทรัพยากรระบบคลาวด์ที่จําเป็น ขั้นตอนเหล่านี้จะสร้างทรัพยากรที่ระบุไว้ด้านล่าง

  • ที่เก็บข้อมูล Cloud Storage ($PRIMUS_INPUT_STORAGE_BUCKET) เพื่อจัดเก็บการแชร์คีย์ส่วนตัวที่เข้ารหัส
  • ที่เก็บข้อมูล Cloud Storage ($PRIMUS_RESULT_STORAGE_BUCKET) เพื่อจัดเก็บผลลัพธ์ของธุรกรรมเนื้อหาดิจิทัล
  • คีย์การเข้ารหัส ($PRIMUS_KEY) และพวงกุญแจ ($PRIMUS_KEYRING) ใน KMS เพื่อเข้ารหัสการแชร์คีย์ส่วนตัว
  • Workload Identity Pool ($PRIMUS_WORKLOAD_IDENTITY_POOL) เพื่อตรวจสอบการอ้างสิทธิ์ตามเงื่อนไขแอตทริบิวต์ที่กำหนดค่าไว้ภายใต้ผู้ให้บริการ
  • บัญชีบริการ ($PRIMUS_SERVICEACCOUNT) ที่แนบกับพูล Workload Identity ที่กล่าวถึงข้างต้น ($PRIMUS_WORKLOAD_IDENTITY_POOL) ซึ่งมีสิทธิ์เข้าถึง IAM ดังต่อไปนี้
  • roles/cloudkms.cryptoKeyDecrypter เพื่อถอดรหัสข้อมูลโดยใช้คีย์ KMS
  • objectViewer เพื่ออ่านข้อมูลจากที่เก็บข้อมูล Cloud Storage
  • roles/iam.workloadIdentityUser สำหรับการเชื่อมต่อบัญชีบริการนี้กับ Workload Identity Pool
./setup_resources.sh

3 สร้างภาระงาน

สร้างบัญชีบริการของเวิร์กโหลด

ตอนนี้คุณจะต้องสร้างบัญชีบริการสำหรับเวิร์กโหลดที่มีบทบาทและสิทธิ์ที่จำเป็น โดยให้เรียกใช้สคริปต์ต่อไปนี้ ซึ่งจะสร้างบัญชีบริการของเวิร์กโหลดสำหรับบริษัท ก. VM ที่เรียกใช้เวิร์กโหลดจะใช้บัญชีบริการนี้

บัญชีบริการของเวิร์กโหลด ($WORKLOAD_SERVICEACCOUNT) จะมีบทบาทต่อไปนี้

  • confidentialcomputing.workloadUser เพื่อรับโทเค็นการรับรอง
  • logging.logWriter เพื่อเขียนบันทึกไปยัง Cloud Logging
  • objectViewer เพื่ออ่านข้อมูลจากที่เก็บข้อมูล Cloud Storage ของ $PRIMUS_INPUT_STORAGE_BUCKET
  • objectUser เพื่อเขียนผลลัพธ์ของภาระงานไปยังที่เก็บข้อมูล Cloud Storage ของ $PRIMUS_RESULT_STORAGE_BUCKET
./create_workload_service_account.sh

สร้างภาระงาน

ขั้นตอนนี้เกี่ยวข้องกับการสร้างอิมเมจ Docker ของภาระงาน เวิร์กโหลดในโค้ดแล็บนี้เป็นแอปพลิเคชัน MPC ของ Node.js แบบง่ายที่ลงนามธุรกรรมดิจิทัลสำหรับการโอนเนื้อหาโดยใช้ส่วนแบ่งคีย์ส่วนตัวที่เข้ารหัส นี่คือรหัสโปรเจ็กต์ภาระงาน โปรเจ็กต์ภาระงานจะมีไฟล์ต่อไปนี้

package.json: ไฟล์นี้มีรายการแพ็กเกจที่ควรใช้สำหรับแอปพลิเคชัน MPC ของเวิร์กโหลด ในกรณีนี้ เราใช้ไลบรารี @google-cloud/kms, @google-cloud/storage, ethers และ fast-crc32c นี่คือไฟล์ package.json ที่เราจะใช้สำหรับโค้ดแล็บนี้

index.js: นี่คือจุดแรกเข้าของแอปพลิเคชันเวิร์กโหลด และระบุคำสั่งที่ควรเรียกใช้เมื่อคอนเทนเนอร์เวิร์กโหลดเริ่มต้นขึ้น นอกจากนี้ เรายังได้แนบตัวอย่างธุรกรรมที่ไม่มีการรับรองซึ่งโดยปกติแล้วแอปพลิเคชันที่ไม่น่าเชื่อถือซึ่งขอให้ผู้ใช้ลงนามจะเป็นผู้ระบุ ไฟล์ index.js นี้จะนําเข้าฟังก์ชันจาก mpc.js ด้วย ซึ่งเราจะสร้างในลำดับถัดไป ด้านล่างนี้คือเนื้อหาของไฟล์ index.js และคุณดูเนื้อหานี้ได้ที่นี่

import {signTransaction, submitTransaction, uploadFromMemory} from './mpc.js';

const signAndSubmitTransaction = async () => {
 
try {
   
// Create the unsigned transaction object
   
const unsignedTransaction = {
     
nonce: 0,
     
gasLimit: 21000,
     
gasPrice: '0x09184e72a000',
     
to: '0x0000000000000000000000000000000000000000',
     
value: '0x00',
     
data: '0x',
   
};

   
// Sign the transaction
   
const signedTransaction = await signTransaction(unsignedTransaction);

   
// Submit the transaction to Ganache
   
const transaction = await submitTransaction(signedTransaction);

   
// Write the transaction receipt
   
uploadFromMemory(transaction);

   
return transaction;
 
} catch (e) {
   
console.log(e);
   
uploadFromMemory(e);
 
}
};

await signAndSubmitTransaction();

mpc.js: ไฟล์นี้คือที่ที่การเซ็นสัญญาธุรกรรมเกิดขึ้น โดยจะนําเข้าฟังก์ชันจาก kms-decrypt และ credential-config ซึ่งเราจะพูดถึงในลำดับถัดไป ด้านล่างนี้คือเนื้อหาของไฟล์ mpc.js และคุณยังดูเนื้อหานี้ได้ที่นี่

import {Storage} from '@google-cloud/storage';
import {ethers} from 'ethers';

import {credentialConfig} from './credential-config.js';
import {decryptSymmetric} from './kms-decrypt.js';

const providers = ethers.providers;
const Wallet = ethers.Wallet;

// The ID of the GCS bucket holding the encrypted keys
const bucketName = process.env.KEY_BUCKET;

// Name of the encrypted key files.
const encryptedKeyFile1 = 'alice_encrypted_key_share';
const encryptedKeyFile2 = 'bob_encrypted_key_share';

// Create a new storage client with the credentials
const storageWithCreds = new Storage({
 
credentials: credentialConfig,
});

// Create a new storage client without the credentials
const storage = new Storage();

const downloadIntoMemory = async (keyFile) => {
 
// Downloads the file into a buffer in memory.
 
const contents =
     
await storageWithCreds.bucket(bucketName).file(keyFile).download();

 
return contents;
};

const provider =
   
new providers.JsonRpcProvider(`http://${process.env.NODE_URL}:80`);

export const signTransaction = async (unsignedTransaction) => {
 
/* Check if Alice and Bob have both approved the transaction
 
For this example, we're checking if their encrypted keys are available. */
 
const encryptedKey1 =
     
await downloadIntoMemory(encryptedKeyFile1).catch(console.error);
 
const encryptedKey2 =
     
await downloadIntoMemory(encryptedKeyFile2).catch(console.error);

 
// For each key share, make a call to KMS to decrypt the key
 
const privateKeyshare1 = await decryptSymmetric(encryptedKey1[0]);
 
const privateKeyshare2 = await decryptSymmetric(encryptedKey2[0]);

 
/* Perform the MPC calculations
 
In this example, we're combining the private key shares
 
Alternatively, you could import your mpc calculations here */
 
const wallet = new Wallet(privateKeyshare1 + privateKeyshare2);

 
// Sign the transaction
 
const signedTransaction = await wallet.signTransaction(unsignedTransaction);

 
return signedTransaction;
};

export const submitTransaction = async (signedTransaction) => {
 
// This can now be sent to Ganache
 
const hash = await provider.sendTransaction(signedTransaction);
 
return hash;
};

export const uploadFromMemory = async (contents) => {
 
// Upload the results to the bucket without service account impersonation
 
await storage.bucket(process.env.RESULTS_BUCKET)
     
.file('transaction_receipt_' + Date.now())
     
.save(JSON.stringify(contents));
};

kms-decrypt.js: ไฟล์นี้มีโค้ดสำหรับการถอดรหัสโดยใช้คีย์ที่จัดการใน KMS ด้านล่างนี้คือเนื้อหาของไฟล์ kms-decrypt.js และคุณยังดูเนื้อหานี้ได้ที่นี่

import {KeyManagementServiceClient} from '@google-cloud/kms';
import crc32c from 'fast-crc32c';

import {credentialConfig} from './credential-config.js';

const projectId = process.env.PRIMUS_PROJECT_ID;
const locationId = process.env.PRIMUS_LOCATION;
const keyRingId = process.env.PRIMUS_ENC_KEYRING;
const keyId = process.env.PRIMUS_ENC_KEY;

// Instantiates a client
const client = new KeyManagementServiceClient({
 
credentials: credentialConfig,
});

// Build the key name
const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);

export const decryptSymmetric = async (ciphertext) => {
 
const ciphertextCrc32c = crc32c.calculate(ciphertext);
 
const [decryptResponse] = await client.decrypt({
   
name: keyName,
   
ciphertext,
   
ciphertextCrc32c: {
     
value: ciphertextCrc32c,
   
},
 
});

 
// Optional, but recommended: perform integrity verification on
 
// decryptResponse. For more details on ensuring E2E in-transit integrity to
 
// and from Cloud KMS visit:
 
// https://cloud.google.com/kms/docs/data-integrity-guidelines
 
if (crc32c.calculate(decryptResponse.plaintext) !==
     
Number(decryptResponse.plaintextCrc32c.value)) {
   
throw new Error('Decrypt: response corrupted in-transit');
 
}

 
const plaintext = decryptResponse.plaintext.toString();

 
return plaintext;
};

credential-config.js: ไฟล์จะจัดเก็บเส้นทางและรายละเอียดของ Workload Identity Pool สำหรับการแอบอ้างเป็นบัญชีบริการ ที่นี่คือไฟล์ credential-config.js ที่เราจะใช้สําหรับโค้ดแล็บนี้

Dockerfile: สุดท้าย เราจะสร้าง Dockerfile ที่จะใช้ในการสร้างอิมเมจ Docker ของภาระงาน โดยกำหนด Dockerfile ตามที่ระบุไว้ที่นี่

FROM node:16.18.0

ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json*", "./"]

RUN npm install --production

COPY . .

LABEL "tee.launch_policy.allow_cmd_override"="true"
LABEL "tee.launch_policy.allow_env_override"="NODE_URL,RESULTS_BUCKET,KEY_BUCKET,PRIMUS_PROJECT_NUMBER,PRIMUS_PROJECT_ID,PRIMUS_WORKLOAD_IDENTITY_POOL,PRIMUS_WIP_PROVIDER,PRIMUS_SERVICEACCOUNT,PRIMUS_ENC_KEYRING,PRIMUS_ENC_KEY"

CMD [ "node", "index.js" ]

หมายเหตุ: LABEL "tee.launch_policy.allow_cmd_override"="true" ใน Dockerfile คือนโยบายการเริ่มที่นักเขียนอิมเมจกำหนด ซึ่งช่วยให้ผู้ดำเนินการลบล้าง CMD ได้เมื่อเรียกใช้เวิร์กโหลด โดยค่าเริ่มต้น ระบบจะตั้งค่า allow_cmd_override เป็นเท็จ ป้ายกํากับ "tee.launch_policy.allow_env_override" จะบอกพื้นที่ทำงานแบบจำกัดว่าผู้ใช้รูปภาพตัวแปรสภาพแวดล้อมใดบ้างที่ใช้ได้

เรียกใช้สคริปต์ต่อไปนี้เพื่อสร้างภาระงานที่จะทำตามขั้นตอนต่อไปนี้

  • สร้าง Artifact Registry($PRIMUS_ARTIFACT_REPOSITORY) เพื่อจัดเก็บอิมเมจ Docker ของ Workload
  • อัปเดตโค้ดภาระงานด้วยชื่อทรัพยากรที่จำเป็น ที่นี่คือรหัสเวิร์กโหลดที่ใช้สำหรับ Codelab นี้
  • สร้าง Dockerfile สำหรับการสร้างอิมเมจ Docker ของโค้ดภาระงาน ดู Dockerfile ได้ที่นี่
  • สร้างและเผยแพร่อิมเมจ Docker ไปยัง Artifact Registry ($PRIMUS_ARTIFACT_REPOSITORY) ที่สร้างขึ้นในขั้นตอนก่อนหน้า
  • ให้สิทธิ์อ่าน $PRIMUS_ARTIFACT_REPOSITORY แก่ $WORKLOAD_SERVICEACCOUNT ซึ่งจําเป็นเพื่อให้คอนเทนเนอร์ภาระงานดึงอิมเมจ Docker ของภาระงานจาก Artifact Registry ได้
./create_workload.sh

สร้างโหนด Blockchain

โหนด Ganache Ethereum

เราต้องสร้างอินสแตนซ์ Ethereum Ganache ก่อนจึงจะให้สิทธิ์เวิร์กโหลดได้ ระบบจะส่งธุรกรรมที่ลงนามแล้วไปยังอินสแตนซ์ Ganache นี้ โปรดจดที่อยู่ IP ของอินสแตนซ์นี้ไว้ หลังจากเรียกใช้คําสั่งด้านล่าง คุณอาจต้องป้อน y เพื่อเปิดใช้ API

gcloud compute instances create-with-container ${ETHEREUM_NODE} \
  --zone=${PRIMUS_PROJECT_ZONE} \
  --tags=http-server \
  --project=${PRIMUS_PROJECT_ID} \
  --shielded-secure-boot \
  --shielded-vtpm \
  --shielded-integrity-monitoring \
  --container-image=docker.io/trufflesuite/ganache:v7.7.3 \
--container-arg=--wallet.accounts=\"0x0000000000000000000000000000000000000000000000000000000000000001,0x21E19E0C9BAB2400000\" \
  --container-arg=--port=80

4 ให้สิทธิ์และเรียกใช้ภาระงาน

ให้สิทธิ์ภาระงาน

ในขั้นตอนนี้ เราจะตั้งค่าผู้ให้บริการ Workload Identity Pool ภายใต้ Workload Identity Pool ($PRIMUS_WORKLOAD_IDENTITY_POOL) โดยจะมีการกำหนดค่าเงื่อนไขแอตทริบิวต์สำหรับ Workload Identity ดังที่แสดงด้านล่าง เงื่อนไขอย่างหนึ่งคือการตรวจสอบว่ามีการดึงข้อมูลอิมเมจเวิร์กโหลดจากที่เก็บอาร์ติแฟกต์ที่คาดไว้

gcloud config set project $PRIMUS_PROJECT_ID
gcloud iam workload-identity-pools providers create-oidc ${PRIMUS_WIP_PROVIDER} \
 --location="${PRIMUS_PROJECT_LOCATION}" \
 --workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
 --issuer-uri="https://confidentialcomputing.googleapis.com/" \
 --allowed-audiences="https://sts.googleapis.com" \
 --attribute-mapping="google.subject='assertion.sub'" \
 --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' && 'STABLE' in assertion.submods.confidential_space.support_attributes && assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' && '$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"

เรียกใช้ภาระงาน

ส่วนนี้จะอธิบายวิธีเรียกใช้เวิร์กโหลดใน VM ข้อมูลที่เป็นความลับ โดยเราจะส่งอาร์กิวเมนต์ TEE ที่จำเป็นโดยใช้ Flag ข้อมูลเมตา นอกจากนี้ เราจะตั้งค่าตัวแปรสภาพแวดล้อมสำหรับคอนเทนเนอร์ของภาระงานโดยใช้ Flag "tee-env-*" รูปภาพมีตัวแปรต่อไปนี้

  • NODE_URL: URL ของโหนด Ethereum ที่จะประมวลผลธุรกรรมที่ลงนาม
  • RESULTS_BUCKET: ที่เก็บข้อมูลผลลัพธ์ธุรกรรม mpc
  • KEY_BUCKET: ที่เก็บข้อมูลซึ่งจัดเก็บคีย์ที่เข้ารหัส mpc
  • PRIMUS_PROJECT_NUMBER: หมายเลขโปรเจ็กต์ที่ใช้สำหรับไฟล์การกําหนดค่าข้อมูลเข้าสู่ระบบ
  • PRIMUS_PROJECT_ID: รหัสโปรเจ็กต์ที่ใช้สำหรับไฟล์การกําหนดค่าข้อมูลเข้าสู่ระบบ ระบบจะเผยแพร่ผลลัพธ์ของการดำเนินการเวิร์กโหลดไปยัง $PRIMUS_RESULT_STORAGE_BUCKET
  • PRIMUS_WORKLOAD_IDENTITY_POOL: พูล Workload Identity ที่ใช้ตรวจสอบการอ้างสิทธิ์
  • PRIMUS_WIP_POROVIDER: ผู้ให้บริการพูล Workload Identity ซึ่งมีเงื่อนไขแอตทริบิวต์ที่จะใช้ตรวจสอบโทเค็นที่แสดงโดยเวิร์กโหลด
  • WORKLOAD_SERVICEACCOUNT: บัญชีบริการของเวิร์กโหลด
gcloud compute instances create $WORKLOAD_VM \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=TERMINATE \
 --scopes=cloud-platform \
 --zone=${PRIMUS_PROJECT_ZONE} \
 --project=${PRIMUS_PROJECT_ID} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
 --service-account=$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com \
 --metadata "^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG~tee-restart-policy=Never~tee-env-NODE_URL=$(gcloud compute instances describe ${ETHEREUM_NODE} --format='get(networkInterfaces[0].networkIP)' --zone=${PRIMUS_PROJECT_ZONE})~tee-env-RESULTS_BUCKET=$PRIMUS_RESULT_STORAGE_BUCKET~tee-env-KEY_BUCKET=$PRIMUS_INPUT_STORAGE_BUCKET~tee-env-PRIMUS_PROJECT_ID=$PRIMUS_PROJECT_ID~tee-env-PRIMUS_PROJECT_NUMBER=$(gcloud projects describe $PRIMUS_PROJECT_ID --format="value(projectNumber)")~tee-env-PRIMUS_WORKLOAD_IDENTITY_POOL=$PRIMUS_WORKLOAD_IDENTITY_POOL~tee-env-PRIMUS_PROJECT_LOCATION=${PRIMUS_PROJECT_LOCATION}~tee-env-PRIMUS_WIP_PROVIDER=$PRIMUS_WIP_PROVIDER~tee-env-PRIMUS_SERVICEACCOUNT=$PRIMUS_SERVICEACCOUNT~tee-env-PRIMUS_KEY=${PRIMUS_KEY}~tee-env-PRIMUS_KEYRING=${PRIMUS_KEYRING}"

ตรวจสอบผลลัพธ์ใน Cloud Storage

คุณดูใบเสร็จธุรกรรมได้ใน Cloud Storage ระบบอาจใช้เวลา 2-3 นาทีจึงจะบูตพื้นที่ทำงานที่ปลอดภัยและแสดงผลลัพธ์ คุณจะทราบว่าคอนเทนเนอร์เสร็จแล้วเมื่อ VM อยู่ในสถานะ "หยุดทำงาน"

  1. ไปที่หน้าเบราว์เซอร์ Cloud Storage
  2. คลิก $PRIMUS_RESULT_STORAGE_BUCKET
  3. คลิกไฟล์ transaction_receipt
  4. คลิก "ดาวน์โหลด" เพื่อดาวน์โหลดและดูการตอบกลับธุรกรรม

หรือจะเรียกใช้คําสั่งต่อไปนี้เพื่อดูผลลัพธ์ก็ได้

gcloud config set project $PRIMUS_PROJECT_ID
gsutil cat gs://$PRIMUS_RESULT_STORAGE_BUCKET/transaction_receipt

หมายเหตุ: หากผลลัพธ์ไม่ปรากฏ ให้ไปที่ $WORKLOAD_VM ในหน้า Cloud Console ของ Compute Engine แล้วคลิก "พอร์ตซีเรียล 1 (คอนโซล)" เพื่อดูบันทึก

ตรวจสอบธุรกรรม Blockchain ของ Ganache

นอกจากนี้ คุณยังดูธุรกรรมในบันทึกบล็อกเชนได้

  1. ไปที่หน้า Cloud Compute Engine
  2. คลิก ${ETHEREUM_NODE} VM
  3. คลิก SSH เพื่อเปิดหน้าต่าง SSH ในเบราว์เซอร์
  4. ในหน้าต่าง SSH ให้ป้อน sudo docker ps เพื่อดูคอนเทนเนอร์ Ganache ที่ทำงานอยู่
  5. ค้นหารหัสคอนเทนเนอร์สำหรับ trufflesuite/ganache:v7.7.3
  6. ป้อน sudo docker logs CONTAINER_ID โดยแทนที่ CONTAINER_ID ด้วยรหัสของ trufflesuite/ganache:v7.7.3
  7. ดูบันทึกของ Ganache และยืนยันว่ามีธุรกรรมแสดงอยู่ในบันทึก

5 ล้างข้อมูล

ที่นี่เป็นสคริปต์ที่ใช้ล้างทรัพยากรที่เราสร้างขึ้นเป็นส่วนหนึ่งของ Codelab นี้ ในการล้างข้อมูลนี้ ระบบจะลบทรัพยากรต่อไปนี้

  • ใส่ที่เก็บข้อมูลที่ใช้เพื่อจัดเก็บการแชร์คีย์ที่เข้ารหัส ($PRIMUS_INPUT_STORAGE_BUCKET)
  • คีย์การเข้ารหัส ($PRIMUS_KEY)
  • บัญชีบริการที่ใช้เข้าถึงทรัพยากรที่ได้รับการปกป้อง ($PRIMUS_SERVICEACCOUNT)
  • พูล Workload Identity ($PRIMUS_WORKLOAD_IDENTITY_POOL)
  • บัญชีบริการของภาระงาน ($WORKLOAD_SERVICEACCOUNT)
  • Workload Compute Instance ($WORKLOAD_VM และ $ETHEREUM_NODE)
  • ที่เก็บข้อมูลผลลัพธ์ที่ใช้จัดเก็บผลลัพธ์ธุรกรรม ($PRIMUS_RESULT_STORAGE_BUCKET)
  • Artifact Registry ที่ใช้ในการจัดเก็บรูปภาพภาระงาน ($PRIMUS_ARTIFACT_REPOSITORY)
./cleanup.sh

หากสำรวจเสร็จแล้ว โปรดพิจารณาลบโปรเจ็กต์

ขั้นตอนถัดไป

ลองดู Codelab ที่คล้ายกันเหล่านี้...

อ่านเพิ่มเติม