-
Notifications
You must be signed in to change notification settings - Fork 22
Standard RESTful API
PowerAuth Cryptography documentation has been moved to: https://developers.wultra.com/docs/develop/powerauth-crypto/Standard-RESTful-API
Please use the new developer portal to access documentation.
In order to assure a standard behavior of various PowerAuth 2.0 implementations, fixed endpoint and request/response structure between PowerAuth 2.0 Client and Intermediate Server Application is specified for the key exchange algorithm.
While the PowerAuth 2.0 Client technically communicates with an Intermediate Server Application, all response data are actually built in PowerAuth 2.0 Server and Intermediate Server Application just forwards data back and forth. Therefore, we will further assume that the phrase "PowerAuth 2.0 Server responds to PowerAuth 2.0 Client" is a shortcut for "Intermediate Server Application requests a response from PowerAuth 2.0 Server and forwards the response to PowerAuth 2.0 Client".
Each PowerAuth 2.0 implementation that is located on a specific base URL then has /pa/
prefixed endpoints by convention.
Following endpoints are published in PowerAuth 2.0 Standard RESTful API:
-
/pa/activation/create
- Create a new activation, perform a key exchange based on short activation ID. -
/pa/activation/status
- Query for an activation status. -
/pa/activation/remove
- Remove an activation (requires authentication). -
/pa/token/create
- Create a token (requires authentication). -
/pa/token/remove
- Remove a token (requires authentication). -
/pa/vault/unlock
- Get a key to unlock secure vault (requires authentication). -
/pa/signature/validate
- Validate a signature (requires authentication).
PowerAuth 2.0 Standard RESTful API uses a unified format for error response body, accompanied with an appropriate HTTP status code. Besides the HTTP error codes that application server may return regardless of server application (such as 404 when resource is not found or 503 when server is down), following status codes may be returned:
Code | Description |
---|---|
200 | OK response, no issues |
400 | Issue with a request format, or issue of the business logic |
401 | Unauthorized, signature validation failed for authenticated endpoints |
All error responses that are produced by the PowerAuth 2.0 Standard RESTful API have following body:
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_CODE",
"message": "ERROR_MESSAGE_IN_ENGLISH"
}
}
Note that in case of PowerAuth, the code and message is usually very generic and does not provide a lot of information. Please consult the server log for details. On application level, use HTTP status codes to determine the type of the issue and present appropriate message to the user.
Exchange the public keys between PowerAuth 2.0 Client and PowerAuth 2.0 Server.
Application activation is a process of key exchange between a PowerAuth 2.0 Client and a PowerAuth 2.0 Server. During this process, an "activation record" is created on the PowerAuth 2.0 Server and related keys are stored on a PowerAuth 2.0 Client.
PowerAuth 2.0 Client sends following data on the server:
-
activationIdShort
- Represents anACTIVATION_ID_SHORT
value (first half of an activation code). -
applicationKey
- Represents an application with a givenAPPLICATION_KEY
which should be entitled to complete the activation. -
activationNonce
- Represents an activation nonce, used as an IV for AES encryption. -
ephemeralPublicKey
- A technical component for AES encryption - a public component of the on-the-fly generated key pair. -
activationName
- Visual representation of the device, for example "Johnny's iPhone" or "Samsung Galaxy S". -
applicationSignature
- Signature using an application secret, to prove that the activation was completed using a given application.SecretKey signatureKey = KeyConversion.secretKeyFromBytes(Base64.decode(APPLICATION_SECRET))
byte[] applicationSignature = Mac.hmacSha256(signatureKey, activationIdShort + "&" + Base64.encode(activationNonce) + "&" + Base64.encode(encryptedDevicePublicKey) + "&" + applicationKey)
-
encryptedDevicePublicKey
- Represents a public keyKEY_DEVICE_PUBLIC
AES encrypted withACTIVATION_OTP
.byte[] encryptedDevicePublicKey = AES.encrypt(KEY_DEVICE_PUBLIC, activationNonce, ACTIVATION_OTP)
-
extras
- Any client side attributes associated with this activation, like a more detailed information about the client, etc.
PowerAuth 2.0 Server verifies the applicationSignature
and if it matches the expected value, it responds with an following data:
-
activationId
- Represents a longACTIVATION_ID
that uniquely identifies given activation records. -
activationNonce
- Represents an activation nonce, used as an IV for AES encryption. -
ephemeralPublicKey
- A technical component for AES encryption - a public component of the on-the-fly generated key pair. -
encryptedServerPublicKey
- Encrypted public keyKEY_SERVER_PUBLIC
of the server.SharedKey EPH_KEY = ECDH.phase(ephemeralPrivateKey, KEY_DEVICE_PUBLIC)
byte[] encryptedServerPublicKey = AES.encrypt(AES.encrypt(KEY_SERVER_PUBLIC, activationNonce, ACTIVATION_OTP), activationNonce, EPH_KEY)
-
serverDataSignature
- Signature of the server data - concatenatedactivationId
bytes andencryptedServerPublicKey
.byte[] activationData = ByteUtils.concat(activationId.getBytes("UTF-8"), encryptedServerPublicKey)
byte[] serverDataSignature = ECDSA.sign(activationData, KEY_SERVER_MASTER_PRIVATE)
After receiving the response, PowerAuth 2.0 Client verifies severDataSignature
using server's public master key KEY_SERVER_MASTER_PUBLIC
and if the signature is OK, it decrypts server public key using it's private master key KEY_DEVICE_PRIVATE
and ACTIVATION_OTP
.
byte[] activationData = ByteUtils.concat(activationId.getBytes("UTF-8"), encryptedServerPublicKey)
signatureOK = ECDSA.verify(activationData, serverDataSignature, KEY_SERVER_MASTER_PUBLIC)
EPH_KEY = ECDH.phase(KEY_DEVICE_PRIVATE, ephemeralPublicKey)
serverPublicKey = AES.decrypt(AES.decrypt(encryptedServerPublicKey, activationNonce, ACTIVATION_OTP), activationNonce, EPH_KEY)
Then, PowerAuth 2.0 Client deduces KEY_MASTER_SECRET
:
KEY_MASTER_SECRET = ECDH.phase(KEY_DEVICE_PRIVATE, serverPublicKey)
After that, it proceeds with key derivation. See a separate chapter "PowerAuth Key Derivation" for details.
Method | POST |
Resource URI | /pa/activation/create |
- Headers:
Content-Type: application/json
{
"requestObject": {
"activationIdShort": "XDA57-24TBC",
"applicationKey": "UNfS0VZX3JhbmRvbQ==",
"activationNonce": "hbmRvbQRUNESF9QVUJMSUNfS0VZX3J==",
"ephemeralPublicKey": "RvbQSF9QRUNEVUJMSUNfS0VZX3Jhbm==",
"activationName": "My iPhone",
"applicationSignature": "SF9QRUNEVUJMSUNfS0VZX3JhbmRvbQ==",
"encryptedDevicePublicKey": "RUNESF9QVUJMSUNfS0VZX3JhbmRvbQ==",
"extras": "Any data in any format (XML, JSON, ...) for application specific purposes"
}
}
- Status Code:
200
- Headers:
Content-Type: application/json
{
"status": "OK",
"responseObject": {
"activationId": "c564e700-7e86-4a87-b6c8-a5a0cc89683f",
"activationNonce": "vbQRUNESF9hbmRQVUJMSUNfS0VZX3J==",
"ephemeralPublicKey": "MSUNfS0VZX3JhbmRvbQNESF9QVUJMSUNfS0VZX3JhbmRvbQNESF9QVUJ==",
"encryptedServerPublicKey": "NESF9QVUJMSUNfS0VZX3JhbmRvbQNESF9QVUJMSUNfS0VZX3JhbmRvbQ==",
"serverDataSignature": "QNESF9QVUJMSUNfS0VZX3JhbmRvbQ=="
}
}
Get the status of an activation with given activation ID. The PowerAuth 2.0 Server response contains an encrypted activation status blob. More information about the format of status blob and encryption can be found in the chapter on activation status cryptography.
This endpoint also returns a customObject
object with custom application specific data. This object may be used for example to provide service specific data (current timestamp, info about service status, ...) in order to minimize number of required request in practical deployments (for example, mobile banking needs to ask for the service status data on application launch).
Method | POST |
Resource URI | /pa/activation/status |
- Headers
Content-Type: application/json
{
"requestObject": {
"activationId": "c564e700-7e86-4a87-b6c8-a5a0cc89683f"
}
}
- Status code:
200
- Headers
Content-Type: application/json
{
"status": "OK",
"responseObject": {
"activationId": "c564e700-7e86-4a87-b6c8-a5a0cc89683f",
"encryptedStatusBlob": "19gyYaW5ZhdGlvblkb521fYWN0aX9JRaAhbG9duZ==",
"customObject": {
"_comment": "Any object data, such as timestamp, service status info, etc."
}
}
}
Remove an activation with given ID, set it's status to REMOVED. Activation can be removed only after successful verification of the signature.
PowerAuth 2.0 Client sends an authenticated request using an activation ID - authentication is carried around using the standard PowerAuth 2.0 signature with at least 2 factors (2FA).
In order to construct the PowerAuth 2.0 Client signature, use /pa/activation/remove
as URI identifier part of the signature data.
Method | POST |
Resource URI | /pa/activation/remove |
- Headers
Content-Type: application/json
X-PowerAuth-Authorization: PowerAuth ...
- Body: empty
- Status code:
200
- Headers
Content-Type: application/json
{
"status": "OK"
}
Create a static token which can be used for repeated requests to data resources which support token based authentication.
The request contains:
-
ephemeralPublicKey
- a Base64 encoded ephemeral public key which is used for response encryption using ECIES scheme.
In case the PowerAuth signature is verified correctly, the server returns a response which contains encrypted ECIES envelope:
-
mac
- MAC signature of the response, Base64 encoded -
encryptedData
- data encrypted using ECIES scheme, Base64 encoded
The encrypted data payload contains following object:
{
"token_id": "d6561669-34d6-4fee-8913-89477687a5cb",
"token_secret": "VqAXEhziiT27lxoqREjtcQ=="
}
Method | POST |
Resource URI | /pa/token/create |
- Headers
Content-Type: application/json
X-PowerAuth-Authorization: PowerAuth ...
- Body:
{
"requestObject": {
"ephemeralPublicKey": "AhntJuqdqTli2sOwb3GtGR7qD0jElYpVI2AlpyNGOiH4"
}
}
- Status code:
200
- Headers
Content-Type: application/json
{
"requestObject": {
"mac": "xvJ1Zq0mOtgvVqbspLhWMt2NJaTDZ5GkPBbcDxXRB9M=",
"encryptedData": "6jeU9S2FeN5i+OWsTWh/iA5Tx5e9JKFW0u1D062lFsMRIQwcNJZYkPoxWXQDIHdT5OIQrxMe4+qH+pNec5HlzBacZPAy3fB3fCc25OJAoXIaBOTatVbAcsuToseNanIX3+ZNcyxIEVj16OoawPhm1w==",
}
}
Remove a previously created token.
Method | POST |
Resource URI | /pa/token/remove |
- Headers
Content-Type: application/json
X-PowerAuth-Authorization: PowerAuth ...
- Body:
{
"requestObject": {
"tokenId": "d6561669-34d6-4fee-8913-89477687a5cb"
}
}
- Status code:
200
- Headers
Content-Type: application/json
{
"requestObject": {
"tokenId": "d6561669-34d6-4fee-8913-89477687a5cb"
}
}
Get the vault unlock key in order to decrypt data stored in the vault, for example the original KEY_DEVICE_PRIVATE
.
PowerAuth 2.0 Client sends an authenticated request using an activation ID - authentication is carried around using the standard PowerAuth 2.0 signature with at least 2 factors (2FA).
In response, PowerAuth 2.0 Server sends a KEY_ENCRYPTION_VAULT
key encrypted using KEY_ENCRYPTION_VAULT_TRANSPORT
key associated with given counter (derived from the KEY_TRANSPORT
master key, see the PowerAuth Key Derivation
chapter for details).
encryptedVaultEncryptionKey = AES.encrypt(KeyConversion.getBytes(KEY_ENCRYPTION_VAULT), ByteUtils.zeroBytes(16), KEY_ENCRYPTION_VAULT_TRANSPORT)
PowerAuth 2.0 Client can later decrypt the key using the inverse mechanism:
encryptedVaultEncryptionKey = AES.encrypt(KeyConversion.getBytes(KEY_ENCRYPTION_VAULT), ByteUtils.zeroBytes(16), KEY_ENCRYPTION_VAULT_TRANSPORT)
Note: Both the signature calculation / validation and KEY_ENCRYPTION_VAULT_TRANSPORT
key derivation should increase the counter CTR
! In other words, if signature uses value of CTR = N
, key derivation should use CTR = N + 1
. For technical reason, the client should compute the KEY_ENCRYPTION_VAULT_TRANSPORT
ahead - we need to assure that only server may be behind the client with a CTR
value, not vice versa.
Method | POST |
Resource URI | /pa/vault/unlock |
- Headers:
Content-Type: application/json
X-PowerAuth-Authorization: PowerAuth ...
- Body:
{
"requestObject": {
"reason": "NOT_SPECIFIED"
}
}
You can provide any "reason" for vault unlocking. Our SDKs use following states by default:
-
PASSWORD_VALIDATE
- call was used to simply validate a password. -
PASSWORD_CHANGE
- call was used to validate a password because of a password change. -
ADD_BIOMETRY
- call was used to enable biometric authentication. -
FETCH_ENCRYPTION_KEY
- call was used to fetch a generic data encryption key. -
SIGN_WITH_DEVICE_PRIVATE_KEY
- call was used to unlock device private key used for ECDSA signatures.
- Status Code:
200
- Headers:
Content-Type: application/json
{
"status": "OK",
"responseObject": {
"activationId": "c564e700-7e86-4a87-b6c8-a5a0cc89683f",
"encryptedVaultEncryptionKey": "QNESF9QVUJMSUNfS0VZX3JhbmRvbQ=="
}
}
Validate a PowerAuth signature using X-PowerAuth-Authorization
HTTP header.
The HTTP request can use the GET
, POST
, PUT
or DELETE
method.
Following signature types are supported:
possession_knowledge
possession_biometry
possession_knowledge_biometry
The request body should contain data used for computing the signature.
Method | GET/POST/PUT/DELETE |
Resource URI | /pa/signature/validate |
- Headers:
Content-Type: application/json
X-PowerAuth-Authorization: PowerAuth ...
- Body:
{
"... signed request data"
}
- Status Code:
200
- Headers:
Content-Type: application/json
{
"status": "OK"
}
- Status Code:
401
- Headers:
Content-Type: application/json
{
"status": "ERROR",
"responseObject": {
"code": "POWERAUTH_AUTH_FAIL",
"message": "Signature validation failed"
}
}
If you need any assistance, do not hesitate to drop us a line at [email protected].
PowerAuth 2.0 Specification
- Overview
- Basic Definitions
- Activation
- Key Derivation
- Checking Status
- Signatures
- MAC Token Based Authentication
- End-To-End Encryption
- Standard REST API
- Implementation Details
- List of Used Keys
Deployment
Applications
- PowerAuth Server
- PowerAuth Admin
- PowerAuth Push Server
- PowerAuth CMD Tool
- PowerAuth Mobile SDK
- SDK for RESTful APIs
- PowerAuth Web Flow
Development
Releases