This challenge requires you to build an HTTP API with 4 endpoints that handle JSON payloads for encryption, decryption, signing, and verification operations.
- Method: POST
- Input: Any JSON payload
- Output: JSON payload with all properties at depth 1 encrypted
- Encryption Algorithm: Base64 (for simplicity)
Example:
Input:
{
"name": "John Doe",
"age": 30,
"contact": {
"email": "john@example.com",
"phone": "123-456-7890"
}
}Output:
{
"name": "some_encrypted_value",
"age": "some_encrypted_value",
"contact": "some_encrypted_value"
}- Method: POST
- Input: Any JSON payload
- Output: Original JSON payload with decrypted values. If some properties contain values which were not encrypted, they must remain unchanged. The
/decryptendpoint should be able to detect encrypted strings and decrypt, returning the decrypted payload as JSON. - Decryption Algorithm: Base64 (for simplicity)
Examples:
Using the output from the /encrypt example as input should return the original payload:
Input:
{
"name": "some_encrypted_value",
"age": "some_encrypted_value",
"contact": "some_encrypted_value"
}Output:
{
"name": "John Doe",
"age": 30,
"contact": {
"email": "john@example.com",
"phone": "123-456-7890"
}
}Unencrypted properties must remain unchanged:
Input:
{
"name": "some_encrypted_value",
"age": "some_encrypted_value",
"contact": "some_encrypted_value",
"birth_date": "1998-11-19"
}Output:
{
"name": "John Doe",
"age": 30,
"contact": {
"email": "john@example.com",
"phone": "123-456-7890"
},
"birth_date": "1998-11-19" // This remains unchanged
}- Method: POST
- Input: Any JSON payload
- Output: JSON payload with a unique "signature" property
- Signature Algorithm: HMAC
- Important Note: The signature must be computed based on the value of the JSON payload, not its string representation. This means the order of properties should not affect the signature.
Examples:
Basic example for an object with two properties:
Input:
{
"message": "Hello World",
"timestamp": 1616161616
}Output:
{
"signature": "a1b2c3d4e5f6g7h8i9j0..."
}The order of properties must not change the signature, which means this example will generate the same signature:
Input:
{
"timestamp": 1616161616,
"message": "Hello World"
}Output:
{
"signature": "a1b2c3d4e5f6g7h8i9j0..."
}- Method: POST
- Input: JSON payload with "signature" and "data" properties
- Output:
- HTTP 204 (No Content) if signature is valid
- HTTP 400 (Bad Request) if signature is invalid
Examples:
Basic example of an object with two properties:
Input:
{
"signature": "a1b2c3d4e5f6g7h8i9j0...",
"data": {
"message": "Hello World",
"timestamp": 1616161616
}
}Output: 204 HTTP response
The same input object with the order of properties changed must produce the same signature:
Input:
{
"signature": "a1b2c3d4e5f6g7h8i9j0...",
"data": {
"timestamp": 1616161616,
"message": "Hello World"
}
}Output: 204 HTTP response
Example when using a tampered signature or payload:
Input:
{
"signature": "a1b2c3d4e5f6g7h8i9j0...",
"data": {
"timestamp": 1616161616,
"message": "Goodbye World"
}
}Output: 400 HTTP response
-
Abstraction: The encryption algorithm (Base64) in the
/encryptand/decryptendpoints should be easily replaceable with another algorithm without significant changes to the codebase. Design your solution with appropriate abstractions. The same principle applies to the signature algorithm used in the/signand/verifyendpoints. -
Consistency: Ensure that
/encryptfollowed by/decryptreturns the original payload. Ensure that a payload signed with/signcan be successfully verified with/verify.
Please submit your completed project by sending your GitHub repository link to the recruiter's email.