The following document provides details to Online Relying Party partner to integrate with Samsung Wallet to get Digital Credentials data issued to Samsung wallet devices from trusted issuers. One of the main motivations to introduce this technology is to enable Samsung Wallet customers to utilize the Digital ID in their wallets to simplify their online interactions that require identity verification. The following are some of the use-cases we expect to satisfy with our Online RP support.
Samsung Online Relying party supports two modalities: Online same-device RPApp-to-WalletApp and Online same-device Web-to-Wallet App. We currently do not support Cross-device functionality.
The identity verification as part of Samsung Wallet is accomplished with the "Verify with Samsung Wallet" button.
Get Started
To utilize Online Relying party use-cases, RP partners first need to on-board on the Samsung Wallet portal
Pre-requisites – Technical and System Requirements
Samsung Wallet currently supports same-device RP functionality only. Device and Android OS version limitations are given below:
Driver's Licenses or State IDs can be added to the following Galaxy devices
Galaxy S Series - S20 or later
Galaxy Z Series - Z Flip 5G, Z Fold 5G, Z Flip 2, and Fold 2 or later
Galaxy A Series - A53, A54
Mobile Driver's License or State ID is only available on devices running Android 12(S) or later
App2App SDK (RpSdk) Requirements
Minimum Android SDK : RpSdk requires a minimum API level of 26
Kotlin : 1.7.10 is required
Integration Steps
The following steps describe the integration process
Step3. Test 'Verify with Samsung Wallet' function and release the function to user
Test overall 'Verify with Samsung Wallet' function.
Remove test mode in Wallet portal after test is done
Expose the 'Verify with Samsung Wallet' function to the user in Partner side.
Wallet Portal On-boarding Information
Please review the attached partner on-boarding guide for the Samsung Wallet portal. The RP partner needs registration information on the Wallet Portal.
Wallet portal currently offers 'Add to Wallet' & ‘Verify with Wallet’ functionality to RP partners. Please proceed with the registration by referring to the URL of the developer site below.
Partner on-boarding details are accessed via URL below: Partner Onboarding
Manage Wallet Cards
To use the online RP function, you need to create a card as a Relying Party type.
Refer to the Manage Wallet Cards
Overall Managing Process
The following image illustrates the process of managing Samsung Wallet cards:
Create Wallet Cards (Draft Status)
Partners can create and manage their wallet cards with this step-by-step guide.
Manage Wallet Cards
Partners can manage all registered wallet cards.
Partners can edit wallet cards and check their status .
General Information
The general information page allows the partner to enter administrative details to manage their cards, as well as to define common parameters for the Samsung Wallet.
Item
Description
Testing Mode
All data generated during testing mode is periodically deleted. Be sure to turn off the 'Testing mode' setting after the test is over.
Pre-defined partner’s wallet card template(Type > Sub Type > Design Type)
Wallet Card custom setting
type
Authentication issuer
Set the Authentication issuer for the Relying Party service to be provided as this Wallet Card. Please select Authentication issuers from the identity provider groups. Only Authentication issuers with the same “Service Location” as the Relying Party service are displayed. ※ The Identity Provider of the “Authentication issuer”is supported depending on the "Service Location" set
Partner Get card data
URL through which a partner receives a card data inquiry API call If a partner uses this API, enter the URL. Otherwise, leave it blank. ※ The attribute could be activated with the approval of a manager.
Partner Send card state
URL through which a partner receives a card data inquiry API call If a partner uses this API, enter the URL. Otherwise, leave it blank. ※ The attribute could be activated with the approval of a manager.
Samsung Server IPs
Samsung Wallet Server IPs which need to be allowed at the partner’s firewall (separately described for inbound and outbound calls)
Service Location
Select a regional limit for the wallet card. If there was no selected location, the wallet card is shown in all locations. If the specified location was selected, the wallet card is shown only in the selected location. Users can 'Verify with Samsung Wallet' only in Service locations where the wallet service is provided. ※ The Identity Provider of the “Authentication issuer” is supported depending on the "Service Location" set.
Main(Headquarters) Location
Check to set it as a 'Main location'. As the company's main service country(head office) for creating and proceeding with wallet cards, notification e-mails such as wallet card approval requests are sent only to the selected main location.
Wallet Card data save in Server
Set whether to store Wallet Card data in the server to protect personal information. If the card has sensitive information, you can contact the Developer Support Team not to save it.
Description
Description of the wallet card
Select Template
Partners can choose from various types of wallet card templates optimized for partners such as boarding pass, ticket, coupon, and digital ID.
※ For RP Partners : Select "Relying Party type > Other sub type" to set the Relying Party Wallet Card.
Partners can select the type of wallet card needed to register from the 'Select Wallet Card Template' pop-up. First, select the Wallet Card Type and then select the Wallet Card Sub Type to select one of the templates belonging to it.
Wallet Card custom setting
You must set the attributes of the "Wallet Card custom setting" according to the Wallet Card Ttype you selected.
※ For RP Partners: The "Authentication issuer" attribute is a unique property of the Relying Party card.
The Identity Provider of the Authentication issuer is supported depending on the "Service Location" set.
e.g. If Service Location is in the US, the Authentication Issuer field only supports an Identity Provider belonging to the US.
When the parent hierarchy value is checked, its children values created later are automatically checked.
In the United States, the Authentication issuer is the state government, and the driver's license can be understood as an mDL (mobile driver's license).
View Wallet Card
Partners can view all the registered information, edit and delete the wallet card.
Launch Wallet Cards (Verifying Status)
Partners can launch and activate cards.
You can activate a card by clicking the Launch button.
Once a card is launched, the button text changes to 'Launched'. The activation cannot be canceled.
When a card is launched, its status changes to 'Verifying', and then to ‘Active’ after administrator approval.
Launch Wallet Cards (Rejected Status)
If the wallet card is rejected after launching, Partners can modify and re-launch.
The administrator registers the reason for rejection when rejecting a launched wallet card
Partners will receive an email from the system, including the reason for rejection
Partners can apply for launching again by checking the reason for rejection and modifying the wallet card information
Testing Mode
Partners can test a card internally to make sure everything works before officially release to the users.
By default, the ‘Testing mode’ option is enabled.
All data generated in testing mode is periodically deleted.
Card exposure is not affected even when the testing mode is enabled.
Be sure to turn off the testing mode after the test is over. (Testing mode ON → Testing mode Off)
Admin Approval (Active Status)
All launched cards are activated after the administrator's approval.
When a card is launched, its status changes to 'Verifying' and then to ‘Active’ after administrator approval.
When the card is activated, it becomes visible to the user.
Verify with Samsung Wallet Integration
To integrate the Wallet, you need to run the ‘Verify with Samsung Wallet’ script into your system. The Verify with Samsung Wallet script is available for both Web and Android platforms. Each system has a different composition. To implement the Verify with Samsung Wallet button,
follow the steps below in order.
Create tokenized card data (cdata). Card data is the actual content data of wallet card and it has several format based on card type. Please refer to Generate_Cdata Sample Code for detail.
Copy the sample Verify with Samsung Wallet script from Partner portal’s Wallet Card page and replace cdata with the data token created above.
Below are ‘Verify with Samsung Wallet’ script guide in Partner portal.
To integrate the ‘Verify with Samsung Wallet’ you may need some base data. You can find this base data and other necessary information on the Partner Portal and the Wallet API Spec . You can also add image beacon in the script for tracking effect analysis.
Sequence/Flow Diagram
This section describes the flows that are two currently supported: the App2App and Web2App ones. RP Partners should select the model based on their integration preference.
Same-device App2App (via Native Wallet SDK)
Diagram with numbered flows
Explanation of each flow
2) Load Button resources
The Verify with Samsung Wallet Integration and the sample code are both supported
3) Check Service Available Devices
This is the process of checking whether the device supports the Verify with Samsung Wallet function. RP Partners can implement it by referring to the provided sample code.
4) Show button with web link
You can implement it by referring to the provided sample code.
Refer to the. Data Transmit Link
7) Verify with Samsung Wallet link
The link will invoke the WalletApp using AppLink technology. In the meantime, the App2app SDK makes a direct connection between the WalletApp and PartnerApp
10) getMdocRequestData(DeviceEngagementBytes)
The WalletApp makes DeviceEngagementBytes according to the ISO-18013-5 and send it to the PartnerApp
11) sendMdocRequestData(sessionEstablishment)
The PartnerApp build sessionEstablishmentBytes (ISO-18013-5) and encrypt it with HKDF (ISO-18013-5, 9.1.1.5 Cryptographic operations)
13) sendMdocResponse(encryptedResponse)
The WalletApp sends an encrypted ISO-18013-5 response payload to the PartnerApp
3) Check Service Available Devices
This is the process of checking whether the device supports the Verify with Samsung Wallet function. RP Partners can implement this by referring to the provided sample code.
4) Show button with web link
RP Partners can implement this by referring to the provided sample code.
Refer to the Data Transmit Link
7) Verify with Samsung Wallet link
The link will invoke the WalletApp using the AppLink technology
10) Transfer DeviceEngagement
The WalletApp makes DeviceEngagementBytes according to the ISO-18013-5 and sends it to the PartnerServer through the Wallet Server
11~12) Request key API (Send Key)
The Wallet Backend Server converts the data received from the request and cardId information into JWT (JWS + JWE) and delivers it to the partner server.
The partner server must decrypt the JWT (JWS + JWE) data again.
The PartnerApp build sessionEstablishmentBytes (ISO-18013-5) and encrypt it with HKDF (ISO-18013-5, 9.1.1.5 Cryptographic operations)
The partner server must create and transmit the data fields required for authentication as JWT (JWS + JWE) in response to the Wallet Backed Server.
14) Send Mdoc response
The WalletApp sends an encrypted ISO-18013-5 response payload to the PartnerServer through the Wallet Server
15) Request auth API (Send authentication data)
The authentication data card information received in step 14 is converted into JWT (JWS+JWE) and transmitted to the partner server.
The partner server must decrypt the JWT (JWS + JWE) data again.
RP Partner can refer to the code links below for decryption, verify.
Cross-device (Not Supported)
Currently, Samsung Wallet does not support Cross-device functionality. This functionality will be added soon.
Data Transmit Link
This is how RP partners can create a Data Transmit Link. It is a method of safely including tokenized data within the (Verify with Samsung Wallet) VWW link.
The format of the VWW link for this method is as follows.
The name Data Transmit Link has been changed from Typical flow
Wallet card identifier issued from Partner portal when the partner manager signs up for partner services and registers the wallet card they want to service.
Hash Path Parameters
#Clip
String(5)
Required
Parameters for the Hash link * The first letter is capitalized
Query Parameters
cdata
String
Required
Actual payload data in basic JSON format to communicate between partners and Samsung Wallet. This must be secured in JWT (JSON Web Token) format. * See the chapter Security for more details.
Refer to the Wallet Cards
This chapter defines Wallet Card data fields for the attributes object of each wallet card type.
The structure for configuring wallet cards follows the defined specification. Configuring the card data in the specified formatted JSON structure is required. See the details for each card type.
Type
Value
Description
Card object
card
Object
Required
Card information.
card.type
String(16)
Required
Wallet Card type
card.subType
String(16)
Required
allet Card sub type
card.data[]
Array of Object
Required
Wallet card data container Allows up to 6 objects at once
data[].refId
String(32)
Required
A unique content identifier defined by the content provider
data[].createdAt
Long(13)
Required
Data creation timestamp. Epoch timestamp in milliseconds. UTC±00:00
data[].updatedAt
Long(13)
Required
Data creation timestamp. Epoch timestamp in milliseconds. UTC±00:00
data[].language
String(8)
Required
Default content language code. e.g., en, ko
data[].attributes
Object
Required
Card data attributes. * Refer to the following chapters for each type
data[].attributes.{fields}
Attribute fields by card type.
data[].localization[]
Array of Object
Optional
Information for multilingual support.
localization[].language
String(8)
Required
Multilingual content language code. e.g., en, ko, etc
localization[].attributes.{fields}
For displaying a given language, ‘data[].attributes’ can be replaced by localized versions. * Refer to the following chapters for each type
To ensure secure card data transmission, it must be tokenized in JWT format. For this purpose, partner will need the certificate obtained using the partner's email account when signing up for the partner portal.
For detailed information on secure data tokenization, partners can refer to the Security chapter.
*Image resources provided by URLs can be cached. Therefore, for the image resource to be replaced immediately, the corresponding URL path must be changed.
Relying Party
‘relyingparty’ cards are used for verifier authentication .
When partners create the Verify with Samsung Wallet button, they will need to create cdata.
This is the data spec included when creating the cdata of relayingparty type.
Wallet card type
Wallet card subtype
relyingparty
Others
Type
Value
Description
attributes{fields}
1
logoImage
String(256)
Required
URL of the logo image. The file size must not be greater than 256 KB.
2
logoImage.darkUrl
String(256)
Required
URL of the logo image. The file size must not be greater than 256 KB.
3
logoImage.lightUrl
String(256)
Required
URL of the logo image. The file size must not be greater than 256 KB.
4
fontColor
String(8)
Optional
Display Color of the font during user authentication.
5
providerName
String(32)
Required
Display name during user authentication
6
clientType
String(32)
Required
Information on whether the client operates as an application or Web.
7
clientPackageName
String(32)
required
If the client is operating as an app, enter the package name, If it works on the web, enter a service name.
For Samsung Wallet integration, partners will need to insert an "Verify with Samsung Wallet" script into their systems. To implement an "Verify with Samsung Wallet" button, partner should follow the procedure below:
Create the tokenized card data (Cdata). Card data is the actual content of the wallet card and it has several formats based on the card type. Refer to the CData Generation Sample Code for details.
Important
The card data token expires in 30 seconds after creation, so it needs to be created right after the user clicks the "Verify with Samsung Wallet” button.
For "Verify with Samsung Wallet" integration, you may also need some base data. You can find that and other necessary information on Partners Portal
Implementing VWW button on the Web
This section explains how to implement an "Verify with Samsung Wallet" button using JavaScript in a web view.
Web Button Reference with Importing API JavaScript
If partner implement the "Verify with Samsung Wallet" button using this script, the button is shown only on the devices that support Samsung Wallet.
To automatically parse <samsung:wallet> HTML tags when the page is loaded, partners should include the following standard JavaScript:
Partners can use these tags or JavaScript functions for the web button if they are rendering HTML and have proper partner permissions. Partners can also use the script by referring to the various attributes.
samsung:wallet HTML Tag
The ‘samsung:wallet’ namespace tag defines the placement and various attributes of the "Verify with Samsung Wallet" web button for Samsung Wallet.
Flag to display the "Verify with Samsung Wallet" image button in one-line format. Default: true (one-line).
locale
String
N
Locale of the "Verify with Samsung Wallet" image button.
rdclickurl
String
Y
URL for logging a button click event. * Value granted from the Partners Portal.
rdimpressionurl
String
Y
URL for logging a button impression event. * Value granted from the Partners Portal.
showforced
String
N
Flag to force the "Verify with Samsung Wallet" button to be displayed. Default: false.
mediatheme
String
N
Load the button’s resources from the media theme policy. There are 4 themes: default, inversion, lightonly, and darkonly. Default: default. *default: Load the button’s theme according to the prefers-color-scheme policy. *inversion: Load the inverse of the default button’s theme. *lightonly: Load the light theme of the default button. *darkonly: Load the dark theme of the default button.
style
String(CSSStyleDeclaration)
N
Load the button with custom style
onshowbutton
Function
N
Callback handler function for the button’s on-show event
onclickbutton
Function
N
Callback handler function for the button’s on-click event. If you register the handler function, you must return a callback or promise value. * Refer to Usage of onClickButton Handler for more details.
samsungWallet.addButton Function
This function allows partners to explicitly render the Samsung Wallet API for the "Verify with Samsung Wallet" web button.
Flag to display the "Verify with Samsung Wallet" image button in one-line format. Default: true (one-line).
locale
String
N
Locale of the "Verify with Samsung Wallet" image button.
RDClickUrl
String
Y
URL for logging a button click event. * Value granted from the Partners Portal.
RDimpressionurl
String
Y
URL for logging a button impression event. * Value granted from the Partners Portal.
showForced
String
N
Flag to force the "Verify with Samsung Wallet" button to be displayed. Default: false.
mediaTheme
String
N
Load the button’s resources from the media theme policy. There are 4 themes: default, inversion, lightonly, and darkonly. Default: default. *default: Load the button’s theme according to the prefers-color-scheme policy. *inversion: Load the inverse of the default button’s theme. *lightonly: Load the light theme of the default button. *darkonly: Load the dark theme of the default button.
style
Object(CSSStyleDeclaration)
N
Load the button with custom style
onShowButton
Function
N
Callback handler function for the button’s on-show event
onClickButton
Function
N
Callback handler function for the button’s on-click event. If you register the handler function, you must return a callback or promise value. * Refer to Usage of onClickButton Handler for more details.
Usage of onClickButton Handler
Partners can choose whether to proceed with the next "Verify with Samsung Wallet" step using a promise or a callback function, if they register a callback handler in onClickButton.
We recommend that partner add the process of generating JWT cdata (add cdata to options.cdata) to this handler, because of the cdata expiration time.
The function parameters are defined as follows.
Attribute
Type
Required
Description
options
Button attributes
N
Attributes of the current button
callback
Function
N
Callback function to pass the flag to proceed. Default: false.
(Promise resolve)
Function
N
Promise-resolved value to pass the flag to proceed Default: false.
Callback to web button process from callback attributes (for ES5)
By executing a callback function with a flag, you can proceed to the next 'Verify with Samsung Wallet' process.
onClickButton: function (options, callback) {
// TODO partner's process
callback(flag)
}
Callback to web button process from returning Promise (for ES6)
By returning a promise with a resolving flag, you can proceed to the next ‘Verify with Samsung Wallet’ process.
onClickButton: async (options) => {
return new Promise(async (resolve, reject) => {
// TODO partner's process (await)
resolve(flag)
})
}
Implementing VWW button on the App
This section explains how to implement an "Verifying with Samsung Wallet" button in the partner’s app.
Please download below sample code and refer it
App2App SDK Integration Specs
Description & Use
Rp SDK is an App2App SDK for Samsung Wallet driver's license service online scenarios.
This SDK provides an implementation for direct communication between the Samsung Wallet and Partner applications.
binding.button.setOnClickListener {
rpClientApis.request("com.samsung.android.spay", UUID.randomUUID().toString(), appLink, object : RpClientApis.OnResponseListener {
override fun onGetMdocRequestData(deviceEngagementBytes: ByteArray): ByteArray? {
Log.i(TAG, "onGetMdocRequestData($deviceEngagementBytes)")
/**
* 1. prepare mDoc request data (ISO-18013-5)
* 2. build sessionEstablishmentBytes (ISO-18013-5)
* 3. Encrypt it with HKDF (ISO-18013-5, 9.1.1.5 Cryptographic operations)
**/
return "encryptedSessionEstablishmentBytes"
}
override fun onMdocResponse(encryptedResponse: ByteArray) {
Log.i(TAG, "onMdocResponse($encryptedResponse)")
/**
* 1. Decrypt it with HKDF (ISO-18013-5, 9.1.1.5 Cryptographic operations)
* 2. CBOR decode it
**/
}
override fun onMdocResponseFailed(exception: Exception) {
Log.i(TAG, "onMdocResponseFailed($exception)")
}
})
}
Error Code Explanation
The below exceptions might occur through the onMdocResponseFailed callback
Exceptions name
Description
RpCommunicationException
This error occurs when the data requested by the listener is incorrect.
RpConnectionFailedException
This occurs when the App 2 App communication between apps is not working. This usually occurs when the target Package Name is written incorrectly
Web2App API Integration Specs
The API specifications that need to be implemented by the RP partner are described below:
Called by Samsung to the RP partner
Send Key
Send the Wallet application key info and return the data field types requested to the client for authentication of the mDL
[Request]
Type
Value
Description
Method
POST
URL
{Partner server URL}/rp/v1.0/{cardId}/{RefId}/key
Headers
Authorization
String (1024)
Required
Credential token. The token can have the prefix "Bearer" as an authorization type, e.g., Bearer <credentials>. * Refer to Authorization Token for more details.
Unique content identifier defined by the content provider
Query Parameter
N/A
Payload
data
String(3000)
Required
JWT data encrypted with the public key information and card type. If decrypted this data is decoded, and it has the following format information. { “data”: “XXXXXXXXXXX”, “card”: { "type": "relyingparty", "subType": "others", "designType": "us-01" } }
Example
POST {Partner server URL}/rp/v1.0/{cardId}/{RefId}/key
Content-Type: application/json
{
“data”: “eyJjdHkiOiJBVVRIIiwidmVyIjoiMiIsInBhcnRuZXJJZCI6InRlc3QiLCJ1dGMiOjE3MTYyMDYzNjAxMTAsImFsZyI6IlJTMjU2In0.ZXlKbGJtTWlPaUpCTVRJNFIwTk5JaXdpWVd4bklqb2lVbE5CTFU5QlJWQXRNalUySW4wLlZ5aFAxS0FnMVJHbzBDN2NIX2pYdGtfODdQbnhrRmpfWkpPcnNSUUs4MnN0OWVxTjEyVzVMOEJaX1d5NGVzMzE3VDNad0pncmpwZWdZOEk3aVlCWWRlOGJ5LXFiMjBLU3RUc3JsSzlPSlFnN1FaM2xZaUxscXlTb0VlbERvd0FPaTRMRy1JUkZWdVlrbXRiNTg3UTd1ZWNuQ1lWWGZWalVEcG01YXBFbDV3SzM1UGZ3d0dkREM2TmowZ1AwbTZ3Nk1kdl9mdDBvZWc2MWZjaGdBYnY0emxMZjU2cVYzM0t6ZjdjbWVpbkJRNnpMSGUtYmFWYXhVZk5Ld2htZWVjUzFTV3laRm1NVlJ6MEFsMnBxa0dQLVJkT1Iza3VzaVo0VjFIdy1aQ2IyVWVwYVdZRU9nUEdrVW1mbTFuOWJWT1ZmZ1NUV1F0SE5pVTFJYVRHTG1DWlpVQS5PMzZrd1g4WmJnQ21wd3o2Ll9KZEhFVXNnbm13b1drdDRMcU4xMUNCaUNTSnUtbWpYV2ZrckxoS0ZVenBsS085ckdXbUdPZ0pqUkF1NTFsOTRYc2VIVWdfWU9NS2RGR1VOMWJhMHB3Y0tFNGtJMEt2dkFOWHprODN0azBjQzROT2F6VzlmOVNTT0RhMU9IMEFoaVFzQzdDeVFqNndNLWFlVk8waEJwSEJkMEdURUh1Z3Exc21vVmxRbjBlSnJqWHM4X3FwcnpLekwtaDFPcFk1aEs1ZUg5Q3NiSms0aEhCNGNmWUlKRUJFZ09BcGZxcGFuMGFSVGFmODhhdXlqSGZHdGRMa0tLWDV0Q0RTajIxSE5TT0FhWTJVWlZrR0hxU0wzNGJabTU5aEZMNVdHa0lJcE9BMHlWUE9tQzNWTFlKV2JsMm85LkFoeDBVYTVGeTZudkxKVXVkeTAzSHc.E07YYl7IoR3885VYKsS5_q1IcpX750uU2Ge5suJSedx3Dr_U0x4tSe9_0NxM46dyWnFUXrUAGfjDnjHIBc707Li9VI3XtyiHwnwEiFydgv1QB9oddkYyZuahXQmJHVUqNcdt6DF2CAqzF5QgMVqfMGSE_t7IPU8vQFXE34DO-sKzj8ftdusS2EcdANBqOKCHih3m39NouBPFhcX68PlPcW50diXlupxwEGniU2t3Co24YlIaKLGac669aCcXDQr34utVUqhTJt_FTXkahAlzoA34_Hj_s82FivIXh1ITD74UOjZSe7IBWya_kVysoZavnmzTz2tH9CbwyCvx8wA”
}
[Response]
Type
Value
Description
HTTP Status code
200 OK
Payload
data
String(3000)
Required
JWT data encrypted with the data field types requested to the client for authentication of the mDL.
[Result]
HTTP status code
Description
200 OK
Success
400 Bad Request
Requests cannot or will not be processed due to something that is perceived to be a client error.
401 Unauthorized
Authorization token is invalid or expired.
500 Internal Server Error
The server encountered an unexpected condition that prevented it from fulfilling the request.
503 Service Unavailable
The server is not ready to handle the request.
Send authentication data
The data is encrypted according to the requested data and then transmitted along with the data card information.
[Request]
Type
Value
Description
Method
POST
URL
{Partner server URL}/rp/v1.0/{cardId}/{RefId}/auth
Headers
Authorization
String (1024)
Required
Credential token. The token can have the prefix "Bearer" as an authorization type, e.g., Bearer <credentials>. * Refer to Authorization Token for more details.
Unique content identifier defined by the content provider
QueryParameter
N/A
Payload
data
String(3000)
Required
JWT data encrypted with the public key information and card type. If decrypted this data is decoded, it has the following format information. { “data”: “XXXXXXXXXXX”, “card”: { "type": "idcard", "subType": "drivers", "designType": "us-01" } }
Example
POST {Partner server URL}/rp/v1.0/{cardId}/{RefId}/auth
Content-Type: application/json
{
“data”: “eyJjdHkiOiJBVVRIIiwidmVyIjoiMiIsInBhcnRuZXJJZCI6InRlc3QiLCJ1dGMiOjE3MTYyMDYzNjAxMTAsImFsZyI6IlJTMjU2In0.ZXlKbGJtTWlPaUpCTVRJNFIwTk5JaXdpWVd4bklqb2lVbE5CTFU5QlJWQXRNalUySW4wLlZ5aFAxS0FnMVJHbzBDN2NIX2pYdGtfODdQbnhrRmpfWkpPcnNSUUs4MnN0OWVxTjEyVzVMOEJaX1d5NGVzMzE3VDNad0pncmpwZWdZOEk3aVlCWWRlOGJ5LXFiMjBLU3RUc3JsSzlPSlFnN1FaM2xZaUxscXlTb0VlbERvd0FPaTRMRy1JUkZWdVlrbXRiNTg3UTd1ZWNuQ1lWWGZWalVEcG01YXBFbDV3SzM1UGZ3d0dkREM2TmowZ1AwbTZ3Nk1kdl9mdDBvZWc2MWZjaGdBYnY0emxMZjU2cVYzM0t6ZjdjbWVpbkJRNnpMSGUtYmFWYXhVZk5Ld2htZWVjUzFTV3laRm1NVlJ6MEFsMnBxa0dQLVJkT1Iza3VzaVo0VjFIdy1aQ2IyVWVwYVdZRU9nUEdrVW1mbTFuOWJWT1ZmZ1NUV1F0SE5pVTFJYVRHTG1DWlpVQS5PMzZrd1g4WmJnQ21wd3o2Ll9KZEhFVXNnbm13b1drdDRMcU4xMUNCaUNTSnUtbWpYV2ZrckxoS0ZVenBsS085ckdXbUdPZ0pqUkF1NTFsOTRYc2VIVWdfWU9NS2RGR1VOMWJhMHB3Y0tFNGtJMEt2dkFOWHprODN0azBjQzROT2F6VzlmOVNTT0RhMU9IMEFoaVFzQzdDeVFqNndNLWFlVk8waEJwSEJkMEdURUh1Z3Exc21vVmxRbjBlSnJqWHM4X3FwcnpLekwtaDFPcFk1aEs1ZUg5Q3NiSms0aEhCNGNmWUlKRUJFZ09BcGZxcGFuMGFSVGFmODhhdXlqSGZHdGRMa0tLWDV0Q0RTajIxSE5TT0FhWTJVWlZrR0hxU0wzNGJabTU5aEZMNVdHa0lJcE9BMHlWUE9tQzNWTFlKV2JsMm85LkFoeDBVYTVGeTZudkxKVXVkeTAzSHc.E07YYl7IoR3885VYKsS5_q1IcpX750uU2Ge5suJSedx3Dr_U0x4tSe9_0NxM46dyWnFUXrUAGfjDnjHIBc707Li9VI3XtyiHwnwEiFydgv1QB9oddkYyZuahXQmJHVUqNcdt6DF2CAqzF5QgMVqfMGSE_t7IPU8vQFXE34DO-sKzj8ftdusS2EcdANBqOKCHih3m39NouBPFhcX68PlPcW50diXlupxwEGniU2t3Co24YlIaKLGac669aCcXDQr34utVUqhTJt_FTXkahAlzoA34_Hj_s82FivIXh1ITD74UOjZSe7IBWya_kVysoZavnmzTz2tH9CbwyCvx8wA”
}
[Response]
Type
Value
Description
HTTP Status code
200 OK 400 Bad Request
[Result]
HTTP status code
Description
200 OK
Success
400 Bad Request
Requests cannot or will not be processed due to something that is perceived to be a client error.
401 Unauthorized
Authorization token is invalid or expired.
500 Internal Server Error
The server encountered an unexpected condition that prevented it from fulfilling the request.
503 Service Unavailable
The server is not ready to handle the request.
Code explanation based on the sample code
JWT (JWS + JWE) decryption between the Wallet Backed Server and partner server
1. Verify by generateing a JWS using the body data
// Generate JWS by the body data
private static SignedJWT parseJWT(final String data) {
try {
return SignedJWT.parse(data);
} catch (ParseException e) {
log.error("parserJWT error class : {}, error message : {}", e.getClass(), e.getMessage());
throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "parserJWT error");
}
}
// Verify JWS using Samsung Public key
public RequestBody getRequestBody(final KeyRing keyRing) {
final SignedJWT signedJWT = JWTUtils.verify(keyRing.getTargetPublicKey(), encryptedData, 60 * 10000); // Verify and generate JWS
try {
final String strBody = JWTUtils.getDecryptedPayloadFrom(keyRing.getSourcePrivateKey(), JWEObject.parse(signedJWT.getPayload().toString())); // Decryption JWE by the JWS
return objectMapper.readValue(strBody, RequestBody.class); // Convert to data format requested by client
} catch (ParseException | JsonProcessingException e) {
log.error("getRequestBody : {}", e.getMessage());
throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "data body parse error");
}
}
public RequestBody getRequestBody(final KeyRing keyRing) {
final SignedJWT signedJWT = JWTUtils.verify(keyRing.getTargetPublicKey(), encryptedData, 60 * 10000); // Verify and generate JWS
try {
final String strBody = JWTUtils.getDecryptedPayloadFrom(keyRing.getSourcePrivateKey(), JWEObject.parse(signedJWT.getPayload().toString())); // Decryption JWE by the JWS
return objectMapper.readValue(strBody, RequestBody.class); // Convert to data format requested by client
} catch (ParseException | JsonProcessingException e) {
log.error("getRequestBody : {}", e.getMessage());
throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "data body parse error");
}
}
Generate MdocEstablishment
1. Generate RSA Key per refId
public class TransactionContext {
private final KeyPair keyPair; // RSA Key
private final byte[] clientEngagement; // Body data received through key API, base64URL decoded value
@EqualsAndHashCode.Exclude
private int encryptMessageCounter = 0; // Count value when encrypted
@EqualsAndHashCode.Exclude
private int decryptMessageCounter = 0; // Count value when decrypted
}
private Cache<String, TransactionContext> contextCache; // RSA key management per refid with memory cache
// Generate and store RSA Key per refId only once upon first request
public TransactionContext setTransactionContext(final String key, final String base64EncodedClientEngagement) {
log.info("base64EncodedClientPublicKey : {}", base64EncodedClientEngagement);
this.contextCache.put(key, new TransactionContext(KeyUtils.generateKeyPair() , Base64Utils.decode(base64EncodedClientEngagement.getBytes())));
return this.getTransactionContextBy(key);
}
// Part of retrieving RAS Key based on refId
public TransactionContext getTransactionContextBy(final String key) {
return Optional.ofNullable(this.contextCache.getIfPresent(key)).orElseThrow(() -> {
log.info("{} is empty", key);
return new CustomException(HttpStatus.BAD_REQUEST, "No key matching the refId");
});
}
@AllArgsConstructor
public class Establishment {
private final TransactionContext context; // Info of client public key , partner private key, public key
private final List<String> strReqs; // Data field information required for authentication to the client
private final KeyRing keyRing; // RSA Key information for JWT(JWS + JWE) encryption and decryption between Wallet Backed Server and partner server.
}
protected CBORObject generate() {
final CBORObject sessionEstablishment = CBORObject.NewMap();
sessionEstablishment.set(E_READER_KEY, CBORObject.FromObjectAndTag(KeyUtils.getEReaderKey(context), TAG_SIZE)); // Generate oneKey by public key in transactionContext
sessionEstablishment.set(DATA, CBORObject.FromObject(CipherUtils.encrypt(context, generateRequestFormat(getRequestCBORObjectsFrom(strReqs))))); // Add request data field information for authentication.
return sessionEstablishment;
}
Generate the response value JWT(JWS + JWE)
1. Generate establishment with JWE
public static String encryptedStringJWE(final Key publicKey, final String data) { // Please enter Samsung Public Key and establishment data
final JWEObject jwe = new JWEObject(
new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128GCM).build(), new Payload(data));
try {
jwe.encrypt(new RSAEncrypter((RSAPublicKey) publicKey));
return jwe.serialize();
} catch (JOSEException e) {
log.error("encryptedStringJWE Exception message : {}", e.getMessage());
throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "encryptedStringJWE error");
}
}
2. Generate JWS by JWE
public static JWSHeader getDefaultJWSHeader(final String ver, final String certificateId, final String partnerId) {
return new JWSHeader.Builder(JWSAlgorithm.RS256)
.contentType("AUTH")
.customParam("partnerId", partnerId) // partner id
.customParam("ver", ver) // version
.customParam("certificateId", certificateId) // partner crt id
.customParam(UTC, TimeUtils.toUTCEpochMilliFrom(TimeUtils.calculateUTCLocalDateTimeFromNow(0)))
.build();
}
public static String generateSignedStringJWS(final JWSHeader jwsHeader, final Key privateKey, final Key publicKey, final String payload) {
try {
final JWSObject jwsObj = new JWSObject(jwsHeader, new Payload(payload));
JWSSigner signer = new RSASSASigner(new RSAKey.Builder((RSAPublicKey) publicKey).privateKey((RSAPrivateKey) privateKey).build());
jwsObj.sign(signer);
return jwsObj.serialize();
} catch (JOSEException e) {
log.error("encryptedStringJWS Exception message : {}", e.getMessage());
throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "generateSignedStringJWS error");
}
}
3. Generate JWT(JWS + JWE)
public PartnerOutputDTO toPartnerOutputDTO() {
final CBORObject generate = this.generate();
final String establishment = Base64.getUrlEncoder().encodeToString(generate.EncodeToBytes());
final String strJWE = JWTUtils.encryptedStringJWE(keyRing.getTargetPublicKey(), establishment);
final JWSHeader jwsHeader = JWTUtils.getDefaultJWSHeader(keyRing.getVersion(), keyRing.getCertificateId(), "partnerId");
return new PartnerOutputDTO(JWTUtils.generateSignedStringJWS(jwsHeader, keyRing.getSourcePrivateKey(), keyRing.getSourcePublicKey(),strJWE));
}
Authentication processing for values in data fields requested for authentication
1. Retrieve transactionContext value stored in cache using refId value
@Override
public Mono<TransactionContext> getContext(final PartnerInputDTO inputDTO) {
return Mono.just(this.transactionContextManager.getTransactionContextBy(inputDTO.getRefId()));
}
2. Processes the decryption process of the request body data like JWT (JWS + JWE) decryption between Wallet Backed Server and partner server.
3. Generate MdocResponse
public class MdocResponse {
private final TransactionContext context; // Managed tranactionContext by refId
private final byte[] data; // Base64URL decoded data after decrypting JWT (JWS + JWE) data.
public MdocResponse(final TransactionContext context, final String inputDTO) {
this.context = context;
this.data = Base64Utils.decode(inputDTO.getBytes(StandardCharsets.UTF_8));
}
}
4. Get the field values requested for authentication from the data in mDocResponse.
public String getData() {
// SessionData = {
// ? "data" : bstr ; Encrypted mdoc response or mdoc request
// ? "status" : uint ; Status code
// }
final CBORObject response = CBORObject.DecodeFromBytes(data);
checkType(response, CBORType.Map);
final CBORObject data = response.get(DATA);
checkType(data, CBORType.ByteString);
return CBORObject.DecodeFromBytes(isEncryptedMode ? CipherUtils.decrypt(this.context, data.GetByteString()) : data.GetByteString()).ToJSONString();
}
5. Create a Session value using the transactionContext value managed by refId and then decrypt it.
private static byte[] processCipher(final CipherMode cipherMode, final TransactionContext context, final byte[] bytes) { // CipherMode : encrypt or decrypt, bytes : Data passed by the client
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
final int counter = CipherMode.ENCRYPT == cipherMode ? context.getEncryptMessageCounter() : context.getDecryptMessageCounter();
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, getSessionKeyIv(cipherMode.identifier, counter));
cipher.init(cipherMode.cipherMode , getSecretKeySpec(context, cipherMode.info), parameterSpec);
return cipher.doFinal(bytes);
} catch (InvalidAlgorithmParameterException | NoSuchPaddingException | IllegalBlockSizeException |
NoSuchAlgorithmException | BadPaddingException | InvalidKeyException e) {
log.error("error type : {}, message :{}", e.getClass(), e.getMessage());
throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR, "processCipher error");
}
}
6. Examining data received from the client.
@Override
public Mono<Void> authentication(final String response) {
log.info("response info : {}", response);
return Mono.empty();
}
Manage Your Cookies
We use cookies to improve your experience on our website and to show you relevant
advertising. Manage you settings for our cookies below.
Essential Cookies
These cookies are essential as they enable you to move around the website. This
category cannot be disabled.
Company
Domain
Samsung Electronics
.samsungdeveloperconference.com
Analytical/Performance Cookies
These cookies collect information about how you use our website. for example which
pages you visit most often. All information these cookies collect is used to improve
how the website works.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Functionality Cookies
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and
tailor the website to provide enhanced features and content for you.
Company
Domain
LinkedIn
.ads.linkedin.com, .linkedin.com
Advertising Cookies
These cookies gather information about your browser habits. They remember that
you've visited our website and share this information with other organizations such
as advertisers.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Preferences Submitted
You have successfully updated your cookie preferences.