Gere o par de chaves
A curva é EC P-256 (prime256v1). Em todos os caminhos abaixo, a chave privada nunca sai da
sua infraestrutura. Não a envie para nós nem para ninguém. Nenhum campo da nossa API aceita
chave privada, e nenhum suporte nosso vai pedir uma.
Gere o par
- OpenSSL
- Node
- Python
- PHP
- Java
- C#
- Go
- Ruby
- Elixir
- Clojure
# privada (guarde em cofre)
openssl ecparam -name prime256v1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt -out privateKey.pem
# pública (é esta que você registra no portal)
openssl ec -in privateKey.pem -pubout -out publicKey.pem
# confira antes de registrar
openssl ec -in privateKey.pem -text -noout | head -3
# Private-Key: (256 bit) ... NIST CURVE: P-256
import { generateKeyPairSync } from 'node:crypto'
import { writeFileSync } from 'node:fs'
const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'P-256' })
writeFileSync('privateKey.pem', privateKey.export({ type: 'pkcs8', format: 'pem' }))
writeFileSync('publicKey.pem', publicKey.export({ type: 'spki', format: 'pem' }))
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
key = ec.generate_private_key(ec.SECP256R1())
with open("privateKey.pem", "wb") as f:
f.write(key.private_bytes(
serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.NoEncryption(),
))
with open("publicKey.pem", "wb") as f:
f.write(key.public_key().public_bytes(
serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo,
))
<?php
$key = openssl_pkey_new([
'private_key_type' => OPENSSL_KEYTYPE_EC,
'curve_name' => 'prime256v1',
]);
openssl_pkey_export($key, $privatePem);
file_put_contents('privateKey.pem', $privatePem);
// A pública sai da privada — é esta que você registra no portal.
file_put_contents('publicKey.pem', openssl_pkey_get_details($key)['key']);
import java.nio.file.*;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;
public class Gen {
static void pem(String path, String type, byte[] der) throws Exception {
String body = Base64.getMimeEncoder(64, "\n".getBytes()).encodeToString(der);
Files.writeString(Path.of(path),
"-----BEGIN " + type + "-----\n" + body + "\n-----END " + type + "-----\n");
}
public static void main(String[] args) throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
generator.initialize(new ECGenParameterSpec("secp256r1"));
KeyPair pair = generator.generateKeyPair();
// getEncoded() já sai nos formatos certos: privada em PKCS#8, pública em SPKI.
pem("privateKey.pem", "PRIVATE KEY", pair.getPrivate().getEncoded());
pem("publicKey.pem", "PUBLIC KEY", pair.getPublic().getEncoded());
}
}
using System.Security.Cryptography;
var ec = ECDsa.Create(ECCurve.NamedCurves.nistP256);
// Os métodos *Pem já exportam nos formatos certos: privada em PKCS#8, pública em SPKI.
File.WriteAllText("privateKey.pem", ec.ExportPkcs8PrivateKeyPem() + "\n");
File.WriteAllText("publicKey.pem", ec.ExportSubjectPublicKeyInfoPem() + "\n");
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"os"
)
func main() {
key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
priv, _ := x509.MarshalPKCS8PrivateKey(key)
pub, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
os.WriteFile("privateKey.pem",
pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: priv}), 0600)
os.WriteFile("publicKey.pem",
pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pub}), 0644)
}
require 'openssl'
key = OpenSSL::PKey::EC.generate('prime256v1')
# private_to_pem exporta em PKCS#8; public_to_pem em SPKI — os formatos que os exemplos leem.
File.write('privateKey.pem', key.private_to_pem)
File.write('publicKey.pem', key.public_to_pem)
key = :public_key.generate_key({:namedCurve, :secp256r1})
# O OTP exporta a privada em SEC1 ("EC PRIVATE KEY"); todo leitor de PEM aceita.
File.write!("privateKey.pem", :public_key.pem_encode([:public_key.pem_entry_encode(:ECPrivateKey, key)]))
{:ECPrivateKey, _v, _priv, {:namedCurve, oid}, point, _} = key
spki = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, {{:ECPoint, point}, {:namedCurve, oid}})
File.write!("publicKey.pem", :public_key.pem_encode([spki]))
(import '[java.security KeyPairGenerator]
'[java.security.spec ECGenParameterSpec]
'[java.util Base64])
(defn pem [path type der]
(spit path (str "-----BEGIN " type "-----\n"
(.encodeToString (Base64/getMimeEncoder 64 (.getBytes "\n")) der)
"\n-----END " type "-----\n")))
(let [pair (.generateKeyPair (doto (KeyPairGenerator/getInstance "EC")
(.initialize (ECGenParameterSpec. "secp256r1"))))]
;; getEncoded ja sai nos formatos certos: privada em PKCS#8, publica em SPKI.
(pem "privateKey.pem" "PRIVATE KEY" (.getEncoded (.getPrivate pair)))
(pem "publicKey.pem" "PUBLIC KEY" (.getEncoded (.getPublic pair))))
Se o arquivo que você for enviar contiver a linha BEGIN PRIVATE KEY ou BEGIN EC PRIVATE KEY, é
o arquivo errado. O que você registra começa com BEGIN PUBLIC KEY.
Cada aba acima é executada e conferida antes de ser publicada: a privada precisa parsear como P-256 e a pública gravada precisa corresponder a ela byte a byte.
No navegador, na tela "Nova credencial de API"
Clique em Gerar chaves. O par é criado no seu browser, a privada é baixada como
privateKey.pem e a pública já entra preenchida no formulário. A privada não trafega: ela nunca
chega aos nossos servidores.
É o caminho mais rápido para começar, e serve bem para o sandbox. Para produção, prefira OpenSSL ou a biblioteca padrão da sua linguagem numa máquina controlada: uma chave que passou por um navegador passou por extensões, cache e histórico de downloads.
Chaves em KMS ou HSM
Suportado e recomendado. Crie uma chave ECC P-256, sign/verify, exporte a pública e registre-a.
O Sign desses serviços devolve assinatura em DER. Mande como está: aceitamos DER e R‖S cru. Veja
assinando requisições.
O que fazer com a privada
Guarde em cofre. Nunca em repositório, nunca em log, nunca em variável de ambiente compartilhada entre times.
Se ela vazar, revogue a credencial no portal e crie outra. Não existe "trocar a chave" mantendo a credencial, e isso é de propósito: uma credencial é um vínculo assinado entre uma chave, uma conta e um perfil. Trocar a chave significa um vínculo novo, ou seja, uma credencial nova.