Executando operações criptográficas com a API GREP11
O IBM Cloud® Hyper Protect Crypto Services fornece uma API do Enterprise PKCS nº 11 (EP11) por gRPC (também chamada de API de GREP11) para acessar remotamente a instância de serviço do Hyper Protect Crypto Services para criptografia e gerenciamento de dados.
Recuperando as suas credenciais do IBM Cloud
Para trabalhar com a API, é necessário gerar suas credenciais de serviço e autenticação. Para reunir suas credenciais:
Gerando uma solicitação de API GREP11
Para acessar remotamente o HSM em nuvem no Hyper Protect Crypto Services para executar operações criptográficas, é necessário gerar uma solicitação de API do GREP11 e transmitir a URL do terminal de API do GREP11, a chave de API do ID de serviço e o terminal do IAM por meio da chamada de API.
Para o plano padrão Hyper Protect Crypto Services, também é possível ativar o TLS mútuo para a API GREP11 para incluir outra camada de autenticação. Para obter mais informações, consulte Ativando a segunda camada de autenticação para conexões do EP11.
Exemplo: gerando dados aleatórios usando a função GenerateRandomRequest()
A API GREP11 suporta linguagens de programação com bibliotecas gRPC. Dois repositórios de amostra do GitHub são fornecidos para você testar a API do GREP11:
É possível usar o exemplo de código de Golang a seguir para gerar dados aleatórios chamando a função GenerateRandom.
Este exemplo assume que pacotes Golang extra necessários são incluídos por meio de instruções de importação, como os pacotes gRPC e http. A declaração import pb "github.com/IBM-Cloud/hpcs-grep11-go/grpc" é usada pelo GREP11 para executar chamadas de função de API.
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")
No exemplo, atualize as variáveis a seguir:
-
Substitua
<grep11_server_address>pelo valor do terminal de API GREP11. Para localizar a URL do terminal em serviço, por meio de sua IU da instância de serviço provisionada, clique na Visão geral >> Conectar > URL do terminal do Enterprise PKCS #11 Como alternativa, é possível recuperar dinamicamente a URL do terminal de API O valor retornado inclui o seguinte. Dependendo se você está usando a rede pública ou privada, use o valor do terminal de serviço público ou privado que é retornado na seçãoep11.{ "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" } }Se você criar suas instâncias após 12 de abril de 2024 em determinadas regiões, poderá ser necessário usar os novos terminais de API com o novo formato como
<instance_ID>.ep11.<REGION>.hs-crypto.appdomain.cloudA data de disponibilidade varia por região. Para obter mais informações sobre as regiões suportadas, as datas de disponibilidade e as novas URLs de terminal, consulte Novos terminais -
Substitua
<ibm_cloud_apikey>pela chave de API de ID de serviço que você criou. A chave API do ID de serviço pode ser criada seguindo a instrução em Gerenciando a chave API do ID de serviço.
Se a solicitação de amostra for processada com sucesso, serão retornados dados aleatórios com comprimento de 16 bytes, conforme especificado em ep11.AES_BLOCKSIZE.
O exemplo de autenticação anterior, bem como mais exemplos de código Golang, podem ser localizados em:
O que vem a seguir
Você está pronto para iniciar o gerenciamento de suas chaves de criptografia e dados. Para descobrir mais sobre o gerenciamento de seus dados usando a função HSM em nuvem do Hyper Protect Crypto Services, confira o doc de referência da API do GREP11.