GREP11 の API を使用した暗号操作の実行
IBM Cloud® サービス・インスタンスにリモートからアクセスしてデータの暗号化と管理を行えるように、Hyper Protect Crypto Services Hyper Protect Crypto Services には Enterprise PKCS #11 (EP11) over gRPC API (別名 GREP11 API) が用意されています。
IBM Cloud 資格情報の取得
API で作業するには、サービス資格情報と認証資格情報を生成する必要があります。 資格情報を収集するには、次のようにします。
GREP11 API 要求の生成
Hyper Protect Crypto Services 上のクラウド HSM にリモートでアクセスして暗号操作を実行するには、 GREP11 API 要求を生成し、API 呼び出しを介して GREP11 API エンドポイント URL、サービス ID API キー、および IAM エンドポイントを渡す必要があります。
Hyper Protect Crypto Services 標準プランの場合、 GREP11 API の相互 TLS を有効にして別の認証層を追加することもできます。 詳しくは、EP11 接続向け認証の第 2 層の有効化を参照してください。
例: GenerateRandomRequest() 関数を使用したランダム・データの生成
GREP11 API は、 gRPC ライブラリーを使用するプログラミング言語をサポートします。 GREP11 API をテストするために次の 2 つのサンプル GitHub リポジトリーが用意されています。
以下の Golang コード・サンプルを使用することで、GenerateRandom 関数を呼び出してランダム・データを生成できます。
この例では、 gRPC および http パッケージなどのインポート・ステートメントによって、必要な追加の Golang パッケージが組み込まれていることを前提としています。
この import pb "github.com/IBM-Cloud/hpcs-grep11-go/grpc" ステートメントが、API 関数呼び出しを実行するために GREP11 で使用されます。
import pb "github.com/IBM-Cloud/hpcs-grep11-go/grpc"
// Data structure and supporting methods used for GREP11 authentication
// IAMPerRPCCredentials type defines the fields required for IBM Cloud IAM authentication
// This type implements the gRPC PerRPCCredentials interface
type IAMPerRPCCredentials struct {
expiration time.Time
updateLock sync.Mutex
AccessToken string // Required if APIKey nor Endpoint are specified - IBM Cloud IAM access token
APIKey string // Required if AccessToken is not specified - IBM Cloud API key
Endpoint string // Required if AccessToken is not specified - IBM Cloud IAM endpoint
}
// GetRequestMetadata is used by GRPC for authentication
func (cr *IAMPerRPCCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
// Set token if empty or Set token if expired
if len(cr.APIKey) != 0 && len(cr.Endpoint) != 0 && time.Now().After(cr.expiration) {
if err := cr.getToken(ctx); err != nil {
return nil, err
}
}
return map[string]string{
"authorization": cr.AccessToken,
}, nil
}
// RequireTransportSecurity is used by gRPC for authentication
func (cr *IAMPerRPCCredentials) RequireTransportSecurity() bool {
return true
}
// getToken obtains a bearer token and the expiration
func (cr *IAMPerRPCCredentials) getToken(ctx context.Context) (err error) {
cr.updateLock.Lock()
defer cr.updateLock.Unlock()
// Check if another thread has updated the token
if time.Now().Before(cr.expiration) {
return nil
}
var req *http.Request
client := http.Client{}
requestBody := []byte("grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey=" + cr.APIKey)
req, err = http.NewRequest("POST", cr.Endpoint+"/identity/token", bytes.NewBuffer(requestBody))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req = req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {
return err
}
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err)
}
defer resp.Body.Close()
iamToken := struct {
AccessToken string `json:"access_token"`
ExpiresIn int32 `json:"expires_in"`
}{}
err = json.Unmarshal(respBody, &iamToken)
if err != nil {
return fmt.Errorf("error unmarshaling response body: %s", err)
}
cr.AccessToken = fmt.Sprintf("Bearer %s", iamToken.AccessToken)
cr.expiration = time.Now().Add((time.Duration(iamToken.ExpiresIn - 60)) * time.Second)
return nil
}
// Generating a GREP11 API function call
// The following IBM Cloud items need to be changed prior to running the sample program
const address = "<grep11_server_address>"
var callOpts = []grpc.DialOption{
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithPerRPCCredentials(&util.IAMPerRPCCredentials{
APIKey: "<ibm_cloud_apikey>",
Endpoint: "https://iam.cloud.ibm.com",
}),
}
conn, err := grpc.Dial(address, callOpts...)
if err != nil {
panic(fmt.Errorf("Could not connect to server: %s", err))
}
defer conn.Close()
cryptoClient := pb.NewCryptoClient(conn)
rngTemplate := &pb.GenerateRandomRequest{
Len: (uint64)(ep11.AES_BLOCK_SIZE),
}
// Generate 16 bytes of random data for the initialization vector
rng, err := cryptoClient.GenerateRandom(context.Background(), rngTemplate)
if err != nil {
panic(fmt.Errorf("GenerateRandom Error: %s", err))
}
iv := rng.Rnd[:ep11.AES_BLOCK_SIZE]
fmt.Println("Generated IV")
この例では、以下の変数を更新します。
-
<grep11_server_address>を GREP11 API エンドポイントの値に置き換えます。 サービス・エンドポイント URL を確認するには、プロビジョンされたサービス・インスタンス UI で、 「概要」 > 「接続」 > 「Enterprise PKCS #11 エンドポイント URL」 をクリックします。 あるいは、 API エンドポイント URL を動的に取得することもできます。 返される値には、以下が含まれます。 パブリック・ネットワークまたはプライベート・ネットワークのどちらを使用するかに応じて、ep11セクションに返されたパブリック・サービス・エンドポイントまたはプライベート・サービス・エンドポイントの値を使用します。{ "instance_id": "<instance_ID>", "kms": { "public": "<instance_ID>.api.<region>.hs-crypto.appdomain.cloud", "private":"<instance_ID>.api.private.<region>.hs-crypto.appdomain.cloud" }, "ep11": { "public": "<instance_ID>.ep11.<region>.hs-crypto.appdomain.cloud", "private":"<instance_ID>.ep11.private.<region>.hs-crypto.appdomain.cloud" } }特定の地域で 2024 年 4 月 12 日より後にインスタンスを作成する場合、
<instance_ID>.ep11.<REGION>.hs-crypto.appdomain.cloudという新しい形式で新しい API エンドポイントを使用する必要が生じることがあります。 利用可能日は地域によって異なります。 サポートされる地域、可用性の日付、および新規エンドポイント URL について詳しくは、 新規エンドポイント を参照してください。 -
<ibm_cloud_apikey>を、作成したサービス ID API キーに置き換えます。 サービス ID API キーは、 サービス ID API キーの管理の手順に従って作成できます。
ep11.AES_BLOCKSIZE で指定されているとおり、サンプル要求が正常に処理されると、長さが 16 バイトのランダム・データが返されます。
前述の認証の例とその他の Golang コード・サンプルは、以下の場所にあります。
次の作業
暗号鍵とデータの管理を開始する準備が整いました。 Hyper Protect Crypto Services のクラウド HSM 機能を使用してデータを管理する方法について詳しくは、GREP11 API リファレンス資料を確認してください。