Encryption Example Using Key Management Service Keys
Encryption example using Key Management Service keys
This is a Java code example for implementing envelope encryption and data signing/verification using a key generated in KMS.
Envelope encryption
It presents an envelope encryption scenario, and you can review the Java, Go, and Python example code and their output generated according to the scenario.
Scenario
- To encrypt password information using the envelope encryption method, a Data Key is issued.
- Encrypt the password using the issued Data Key information.
- Encrypt the password and encrypted Data Key information using envelope encryption and store them in a JSON file.
Java example code
This is a Java example code written according to the provided scenario.
// URI
static String KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }};
// END POINT
static String KMS_API_DECRYPT = "/v1/kms/openapi/decrypt/%s";
static String KMS_API_CREATE_DATAKEY = "/v1/kms/openapi/datakey/%s";
// KEY ID
static String KEY_ID = {{마스터 키 ID}};
createEnvelop() {
// 새로운 데이터 키 생성을 요청
String encryptedDataKey = getDataKey();
// 암호화를 할 데이터
String example_json_data = "{\"PASSWORD\":\"SECRET_CREDENTIAL\"}";
// 암호화된 데이터 봉투(Envelop encryption)
String envelope = encryptData(example_json_data, encryptedDataKey);
// 이 예제 코드에서는 암호화된 데이터 봉투를 파일로 저장
File envelopeFile = new File("envelope.json");
}
getDataKey() {
String endPoint = String.format(KMS_API_CREATE_DATAKEY, KEY_ID);
String url = KMS_API_BASE_URI + endPoint;
JSONObject data = new JSONObject();
data.put("key_type", "plaintext");
JSONObject respJsonObject = callApi(endPoint, data.toJSONString());
return respJsonObject.get("ciphertext").toString();
}
encryptData() {
Map<String, String> envelope = new HashMap<>();
// 데이터 키 복호화
String dataKey = decryptDataKey(encryptedDataKey);
// Cipher Class 사용 (사용자가 기 사용 중인 암호화 알고리즘 사용 가능)
SecretKey secretKey = new SecretKeySpec(decodeBase64(dataKey), "{사용자 선택 알고리즘}");
Cipher cipher = Cipher.getInstance("{사용자 선택 알고리즘}");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] cipherText = cipher.doFinal(obj.toString().getBytes());
envelope.put("encryptedKey", encryptedDataKey);
envelope.put("cipherText", encodeBase64(cipherText));
envelope.put("iv", encodeBase64(iv));
return JSONValue.toJSONString(envelope);
}
decryptDataKey() {
String endPoint = String.format(KMS_API_DECRYPT, KEY_ID);
JSONObject data = new JSONObject();
data.put("cipherText", sealedKey);
JSONObject respJsonObject = callApi(endPoint, data.toJSONString());
String plaintext = (respJsonObject.get("plaintext")).toString();
return plaintext;
}
Go example code
This is a Go example code written based on the provided scenario.
// URI
const KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
// END POINT
const KMS_API_DECRYPT = "/v1/kms/openapi/decrypt/%s"
const KMS_API_CREATE_DATAKEY = "/v1/kms/openapi/datakey/%s"
// KEY ID
const KEY_ID = {{마스터 키 ID}}
createEnvelop() {
// 새로운 데이터 키 생성을 요청
encryptedDataKey := getDataKey()
// 암호화를 할 데이터
example_json_data := "{\"PASSWORD\":\"SECRET_CREDENTIAL\"}"
// 암호화된 데이터 봉투(Envelop encryption)
envelope := encryptData(example_json_data, encryptedDataKey)
// 이 예제 코드에서는 암호화된 데이터 봉투를 파일로 저장
file, _ := os.Create("envelope.json")
defer file.Close()
file.WriteString(envelope)
}
getDataKey() {
endPoint := fmt.Sprintf(KMS_API_CREATE_DATAKEY, KEY_ID)
data := map[string]interface{}{
"key_type": "plaintext",
}
jsonData, _ := json.Marshal(data)
respJsonObject := callApi(endPoint, jsonData)
info := &KMSDatakeyInfo{}
json.Unmarshal([]byte(respJsonObject), info)
return info.DataKey
}
encryptData() {
envelope := make(map[string]string)
// 데이터 키 복호화
dataKey := decryptDataKey(encryptedDataKey)
secretKey, _ := base64.StdEncoding.DecodeString(dataKey)
// Cipher Class 사용
block, _ := {사용자 선택 알고리즘}.NewCipher(secretKey)
cipherText := make([]byte, {사용자 선택 알고리즘}.BlockSize+len(example_json_data))
iv := cipherText[:{사용자 선택 알고리즘}.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCFBEncrypter(block, iv)
mode.XORKeyStream(cipherText[{사용자 선택 알고리즘}.BlockSize:], []byte(example_json_data))
envelope["encryptedKey"] = encryptedDataKey
envelope["cipherText"] = base64.StdEncoding.EncodeToString(cipherText)
envelope["iv"] = base64.StdEncoding.EncodeToString(iv)
jsonString, _ := json.Marshal(envelope)
return string(jsonString)
}
decryptDataKey() {
endPoint := fmt.Sprintf(KMS_API_DECRYPT, KEY_ID)
data := map[string]interface{}{
"cipherText": sealedKey,
}
jsonData, _ := json.Marshal(data)
respJsonObject := callApi(endPoint, jsonData)
info := &KMSDecryptInfo{}
json.Unmarshal([]byte(respJsonObject), info)
return info.DecryptedData
}
Python example code
This is a Python example code written according to the presented scenario.
# URI
KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
# END POINT
KMS_API_DECRYPT = "/v1/kms/openapi/decrypt/"
KMS_API_CREATE_DATAKEY = "/v1/kms/openapi/datakey/"
# KEY ID
KEY_ID = {{마스터 키 ID}}
create_envelop()
# 새로운 데이터 키 생성을 요청
encrypted_data_key = get_dataKey()
# 암호화를 할 데이터
example_json_data = {"PASSWORDTEST":"SECRET_CREDENTIALTEST"}
json_data_str = json.dumps(example_json_data)
# 암호화된 데이터 봉투(Envelop encryption)
envelope = encrypt_data(json_data_str,encrypted_data_key)
# 이 예제 코드에서는 암호화된 데이터 봉투를 파일로 저장
with open("envelope.json", "w") as file:
file.write(envelope)
get_dataKey()
end_point = f"{KMS_API_CREATE_DATAKEY}{KEY_ID}"
data = {
"key_type": "plaintext"
}
response_object = call_api(end_point, data)
data_key = response_object.get("ciphertext", "")
return data_key
encrypt_data()
envelope = {}
# 데이터 키 복호화
dataKey = decrypt_data_key(encrypted_data_key)
decoded_data_key = base64.b64decode(dataKey)
# Cipher Class 사용
iv = get_random_bytes(16)
cipher = {사용자 선택 알고리즘}.new(decoded_data_key, {사용자 선택 알고리즘}.MODE_CBC, iv)
data_to_encrypt = obj
data_bytes = data_to_encrypt.encode()
padded_data = pad(data_bytes, {사용자 선택 알고리즘}.block_size)
cipher_text = cipher.encrypt(padded_data).hex()
envelope["encryptedKey"] = encrypted_data_key
envelope["cipherText"] = cipher_text
envelope["iv"] = base64.b64encode(iv).decode()
return json.dumps(envelope)
decrypt_data_key()
end_point = f"{KMS_API_DECRYPT}{KEY_ID}"
data = {}
data["cipherText"] = sealed_key
resp_json_object = call_api(end_point,data)
plaintext = resp_json_object.get("decryptedData")
return plaintext
Example code result
Displays the result of the example code.
{
"cipherText":"d3S81rzaGAl8U12LlKSlRbDekPlGuibTntXX962KCjBIKuXdPOG8N8vk3Jet8lyG",
"iv":"0kP7QKZ6BUeQPlThk4tySA==",
"encryptedKey":"vault:v1:KJjjLtGHTbaV5N8LWC5O9eMDCaJVeff5SM\/MAYseugjiqiXFVgdXaKXg6kym0NmjHkO\/wLPsa+YK0aVk"
}
Use envelope encryption
You can present an envelope encryption usage scenario and view the Java, Go, and Python example code and results written according to the scenario.
Scenario
- Decrypt the Data Key of the encrypted envelope file.
- Decrypt the encrypted data of the envelope file using the decrypted Data Key.
Java example code
This is a Java example code written according to the provided scenario.
// URI
static String KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }};
// END POINT
static String KMS_API_DECRYPT = "/v1/kms/openapi/decrypt/%s";
// KEY ID
static String KEY_ID = {{마스터 키 ID}};;
getData() {
// 암호화된 데이터 봉투(Envelop encryption)
String envelope = new String(Files.readAllBytes(Paths.get("envelope.json")));
JSONParser parser = new JSONParser();
JSONObject envelopeJson = (JSONObject) parser.parse(envelope);
String encryptedDataKey = envelopeJson.get("encryptedKey").toString();
String cipherText = envelopeJson.get("cipherText").toString();
String iv = envelopeJson.get("iv").toString();
return decryptData(cipherText, encryptedDataKey, iv);
}
decryptData() {
String dataKey = decryptDataKey(encryptedDataKey);
IvParameterSpec ivParameterSpec = new IvParameterSpec(decodeBase64(iv));
SecretKey secretKey = new SecretKeySpec(decodeBase64(dataKey), "{사용자 선택 알고리즘}");
Cipher cipher = Cipher.getInstance("{사용자 선택 알고리즘}");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] plaintext = cipher.doFinal(decodeBase64(cipherText));
return new String(plaintext);
}
decryptDataKey() {
String endPoint = String.format(KMS_API_DECRYPT, KEY_ID);
JSONObject data = new JSONObject();
data.put("cipherText", sealedKey);
JSONObject respJsonObject = callApi(endPoint, data.toJSONString());
String plaintext = (respJsonObject.get("plaintext")).toString();
return plaintext;
}
Go example code
This is a Go example code written according to the presented scenario.
// URI
const KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
// END POINT
const KMS_API_DECRYPT = "/v1/kms/openapi/decrypt/%s"
// KEY ID
const KEY_ID = {{마스터 키 ID}}
getData() {
// 암호화된 데이터 봉투(Envelop encryption) 불러오기
jsonData, _ := os.ReadFile("envelope.json")
var envelope map[string]interface{}
if err := json.Unmarshal(jsonData, &envelope); err != nil {
fmt.Println("JSON 파싱 오류:", err)
os.Exit(1)
}
encryptedDataKey := envelope["encryptedKey"].(string)
cipherText := envelope["cipherText"].(string)
iv := envelope["iv"].(string)
return decryptData(cipherText, encryptedDataKey, iv)
}
decryptData() {
dataKey := decryptDataKey(encryptedDataKey)
ciphertext, _ := base64.StdEncoding.DecodeString(cipherText)
dataKeyBytes, _ := base64.StdEncoding.DecodeString(dataKey)
decodedData := ciphertext[{사용자 선택 알고리즘}.BlockSize:]
ivparam := ciphertext[{사용자 선택 알고리즘}.BlockSize]
block, _ := {사용자 선택 알고리즘}.NewCipher(dataKeyBytes)
mode := cipher.NewCFBDecrypter(block, ivparam)
mode.XORKeyStream(decodedData, decodedData)
decryptedData := string(decodedData)
return decryptedData
}
decryptDataKey() {
endPoint := fmt.Sprintf(KMS_API_DECRYPT, KEY_ID)
data := map[string]interface{}{
"cipherText": sealedKey,
}
jsonData, _ := json.Marshal(data)
respJsonObject := callApi(endPoint, jsonData)
info := &KMSDecryptInfo{}
json.Unmarshal([]byte(respJsonObject), info)
return info.DecryptedData
}
Python example code
This is a Python example code written according to the presented scenario.
# URI
KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
# END POINT
KMS_API_DECRYPT = "/v1/kms/openapi/decrypt/"
# KEY ID
KEY_ID = {{마스터 키 ID}}
get_data()
# 암호화된 데이터 봉투(Envelop encryption) 열기
with open("envelope.json", "r") as file:
envelope = file.read()
envelope_json = json.loads(envelope)
encrypted_data_key = envelope_json["encryptedKey"]
cipher_text = envelope_json["cipherText"]
iv = envelope_json["iv"]
return decrypt_data(cipher_text, encrypted_data_key, iv)
decrypt_data()
data_key = decrypt_data_key(encrypted_data_key)
iv_bytes = base64.b64decode(iv)
decoded_data_key = base64.b64decode(data_key)
cipher_txt = bytes.fromhex(cipher_text)
cipher = {사용자 선택 알고리즘}.new(decoded_data_key, {사용자 선택 알고리즘}.MODE_CBC, iv_bytes)
plain_text_bytes = unpad(cipher.decrypt(cipher_txt), {사용자 선택 알고리즘}.block_size)
plain_text = plain_text_bytes.decode('utf-8')
return plain_text
decrypt_data_key()
end_point = f"{KMS_API_DECRYPT}{KEY_ID}"
data = {}
data["cipherText"] = sealed_key
resp_json_object = call_api(end_point,data)
plaintext = resp_json_object.get("decryptedData")
return plaintext
Example code result
Displays the result of the example code.
{"PASSWORD":"SECRET_CREDENTIAL"}
Use data signature
It provides a data signing usage scenario to guarantee data integrity, and you can review the Java, Go, and Python example code and their results as written according to the scenario.
Scenario
- Call the OpenAPI to sign the data.
- The signed data is enveloped and saved as a JSON file.
Java example code
This is a Java example code written according to the provided scenario.
// URI
static String KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }};
// END POINT
static String KMS_API_SIGN = "/v1/kms/openapi/sign/%s";
// KEY ID
static String KEY_ID = {{마스터 키 ID}};
signEnvelop() {
// 서명 데이터 봉투(Envelop encryption)
String envelope = sign();
// 이 예제 코드에서는 서명 데이터 봉투를 파일로 저장
File envelopeFile = new File("signEnvelope.json");
OutputStream os = new BufferedOutputStream(new FileOutputStream(envelopeFile));
try {
os.write(envelope.getBytes());
} finally {
os.close();
}
}
sign() {
Map<String, String> envelope = new HashMap<>();
String example_credential = "SCP KMS Sign Test!!!";
String endPoint = String.format(KMS_API_SIGN, KEY_ID);
JSONObject data = new JSONObject();
data.put("input", encodeToBase64(example_credential));
JSONObject respJsonObject = callApi(endPoint, data.toJSONString());
envelope.put("signature", respJsonObject.get("signature").toString());
if(respJsonObject.get("batch_results") != null) {
envelope.put("batch_results", respJsonObject.get("batch_results").toString());
}
return JSONValue.toJSONString(envelope);
}
Go example code
This is a Go example code written according to the presented scenario.
// URI
const KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
// END POINT
const KMS_API_SIGN = "/v1/kms/openapi/sign/%s"
// KEY ID
const KEY_ID = {{마스터 키 ID}}
signEnvelop() {
// 서명 데이터 봉투(Envelop encryption)
envelope := sign()
// 이 예제 코드에서는 서명 데이터 봉투를 파일로 저장
file, _ := os.Create("signEnvelope.json")
defer file.Close()
file.WriteString(envelope)
}
sign() {
envelope := make(map[string]string)
example_credential := "SCP KMS Sign Test!!!"
endPoint := fmt.Sprintf(KMS_API_SIGN, KEY_ID)
data := map[string]interface{}{
"input": base64.StdEncoding.EncodeToString([]byte(example_credential)),
}
jsonData, _ := json.Marshal(data)
respJsonObject := callApi(endPoint, jsonData)
info := &KMSSignInfo{}
json.Unmarshal([]byte(respJsonObject), info)
envelope["signature"] = info.Signature
jsonString, _ := json.Marshal(envelope)
return string(jsonString)
}
Python example code
This is a Python example code written according to the presented scenario.
# URI
KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
# END POINT
KMS_API_SIGN = "/v1/kms/openapi/sign/"
# KEY ID
KEY_ID = {{마스터 키 ID}}
sign_envelop()
# 서명 데이터 봉투(Envelop encryption)
envelope = sign()
# 이 예제 코드에서는 서명 데이터 봉투를 파일로 저장
with open("signEnvelope.json", "w") as file:
file.write(envelope)
sign()
envelope = {}
example_credential = "SCP KMS Sign Test!!!"
end_point = f"{KMS_API_SIGN}{KEY_ID}"
credential_bytes = example_credential.encode('utf-8')
data = {
"input": base64.b64encode(credential_bytes).decode('utf-8')
}
resp_json_object = call_api(end_point,data)
envelope["signature"] = resp_json_object.get("signature")
return json.dumps(envelope)
Example code result
Displays the result of the example code.
{
"signature":"vault:v1:qHGf4ALkTao1Yy\/lpSbLQ2l8YVpsHWBP6ic3Ux1BKSodQQxnEIrjPyUwXXQ1NZfGSVxdeVe5Y6kb0nUPNADQpzkOh9\/e8T\/QCOs9==",
"projectId":"PROJECT-qWrHRJX5sZnTkopcr9N1dk"
}
Use data validation
It presents a verification usage scenario for validating data integrity, and you can view the Java, Go, and Python example code and their results written according to the scenario.
Scenario
- Retrieves the signature value of the signed envelope file.
- Validates the signed data and outputs the result.
Java example code
This is a Java example code written according to the provided scenario.
// URI
static String KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }};
// END POINT
static String KMS_API_VERIFY = "/v1/kms/openapi/verify/%s";
// KEY ID
static String KEY_ID = {{마스터 키 ID}};
getSign() {
// 서명 데이터 봉투(Envelop encryption)
String envelope = new String(Files.readAllBytes(Paths.get("signEnvelope.json")));
JSONParser parser = new JSONParser();
JSONObject envelopeJson = (JSONObject) parser.parse(envelope);
String signature = envelopeJson.get("signature").toString();
return verify(signature);
}
verify() {
String endPoint = String.format(KMS_API_VERIFY, KEY_ID);
JSONObject data = new JSONObject();
data.put("input", "U0NQIEtNUyBTaWduIFRlc3QhISE=");
data.put("signature", signature);
JSONObject respJsonObject = callApi(endPoint, data.toJSONString());
String valid = (respJsonObject.get("valid")).toString();
return valid;
}
Go example code
This is a Go example code written according to the presented scenario.
// URI
const KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
// END POINT
const KMS_API_VERIFY = "/v1/kms/openapi/verify/%s"
// KEY ID
const KEY_ID = {{마스터 키 ID}}
getSign() {
// 서명 데이터 봉투(Envelop encryption) 불러오기
jsonData, _ := os.ReadFile("signEnvelope.json")
var envelope map[string]interface{}
if err := json.Unmarshal(jsonData, &envelope); err != nil {
fmt.Println("JSON 파싱 오류:", err)
os.Exit(1)
}
signature := envelope["signature"].(string)
return verify(signature)
}
verify() {
endPoint := fmt.Sprintf(KMS_API_VERIFY, KEY_ID)
data := map[string]interface{}{
"input": "U0NQIEtNUyBTaWduIFRlc3QhISE=",
"signature": signature,
}
jsonData, _ := json.Marshal(data)
respJsonObject := callApi(endPoint, jsonData)
info := &KMSVerifyInfo{}
json.Unmarshal([]byte(respJsonObject), info)
return info.Valid
}
Python example code
This is a Python example code written according to the presented scenario.
# URI
KMS_API_BASE_URI = {{ OpenAPI 가이드의 URL 참조 }}
# END POINT
KMS_API_VERIFY = "/v1/kms/openapi/verify/"
# KEY ID
KEY_ID = {{마스터 키 ID}}
get_sign()
# 서명 데이터 봉투(Envelop encryption) 열기
with open("signEnvelope.json", "r") as file:
envelope = file.read()
envelope_json = json.loads(envelope)
signature = envelope_json["signature"]
return verify(signature)
verify()
end_point = f"{KMS_API_VERIFY}{KEY_ID}"
data = {
"input": "U0NQIEtNUyBTaWduIFRlc3QhISE=",
"signature": signature
}
resp_json_object = call_api(end_point,data)
valid = resp_json_object.get("valid")
return valid
Example code result
Displays the result of the example code.
{
"valid": true
}