A Python library for supporting GovESB (Government Enterprise Service Bus) Integration
Project description
GovESB Python Package
A comprehensive Python library for integrating with GovESB (Government Enterprise Service Bus), providing secure communication, data encryption, signature verification, and seamless API interactions.
Features
- 🔐 Cryptographic Support: RSA and ECC (Elliptic Curve Cryptography) for secure data transmission
- 📝 Data Format Support: JSON and XML data formats
- 🔑 Token Management: Automatic OAuth2 token acquisition and management
- ✅ Signature Verification: Built-in signature verification for received data
- 📤 Request Signing: Automatic request signing before sending to GovESB
- 🔄 Push/Pull Modes: Support for both PUSH and PULL connection modes
- 🛡️ Security: Industry-standard cryptographic algorithms (SHA256withRSA, ECDSA)
Installation
Install the package from PyPI:
pip install govesb
Or install from source:
git clone https://github.com/LarryMatrix/govesb.git
cd govesb
pip install .
Requirements
- Python 3.7 or higher
- cryptography >= 44.0.0
- requests >= 2.32.0
- xmltodict >= 0.14.0
Data Structure Format
GovESB uses a standardized data structure for both sending and receiving data. All messages follow this format:
{
"data": {
"apiCode": "string",
"esbBody": {
"ephemeralKey": "base64-encoded-public-key",
"iv": "initialization-vector",
"encryptedData": "base64-encoded-encrypted-data"
}
},
"signature": "base64-encoded-signature"
}
Fields:
data.apiCode: The API code identifying the specific GovESB endpointdata.esbBody: Contains the encrypted payloadephemeralKey: Ephemeral public key used for ECIES encryption (base64-encoded PEM format)iv: Initialization vector for AES encryptionencryptedData: The actual encrypted data (base64-encoded)
signature: ECDSA signature of the entiredataobject (base64-encoded)
The library handles signature verification automatically. If you need to decrypt the esbBody.encryptedData, you'll need to implement ECIES decryption using the ephemeralKey, iv, and your private key.
Quick Start
Receiving Data from GovESB
When your system receives data from GovESB, you need to verify the signature and extract the payload. The received data structure contains encrypted data:
import json
import requests
from govesb import DataFormatEnum, ESBHelper
# Configuration
destination_url = "https://your-destination.com/api/endpoint"
destination_username = "system-username"
destination_password = "password"
govesb_public_key = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
# Received data from GovESB (with signature and encrypted esbBody)
sample_data = '''
{
"data": {
"apiCode": "YOUR_API_CODE",
"esbBody": {
"ephemeralKey": "BASE64_ENCODED_EPHEMERAL_PUBLIC_KEY",
"iv": "INITIALIZATION_VECTOR",
"encryptedData": "BASE64_ENCODED_ENCRYPTED_DATA"
}
},
"signature": "BASE64_ENCODED_SIGNATURE"
}
'''
# Verify signature and extract data
response_data = ESBHelper.verify_and_extract_data(
received_data=sample_data,
format=DataFormatEnum.JSON,
public_key=govesb_public_key
)
# Check if verification was successful
if response_data.has_data:
# Parse the verified data to access apiCode and encrypted esbBody
verified_json = json.loads(response_data.verified_data)
api_code = verified_json.get('data', {}).get('apiCode')
esb_body = verified_json.get('data', {}).get('esbBody')
print("API Code:", api_code)
print("Encrypted ESB Body:", esb_body)
# Note: If esbBody contains encrypted data, you'll need to decrypt it
# using your private key and the ephemeralKey, iv, and encryptedData fields
# The decryption process depends on your specific implementation
# Process the verified data
response = requests.post(
url=destination_url,
json=verified_json,
auth=(destination_username, destination_password)
)
print("Response:", response.text)
else:
print("Signature Verification Failed:", response_data.message)
Sending Data to GovESB
To send data to GovESB, you need to authenticate, sign the request, and send it. The data will be encrypted and signed before sending:
from govesb import DataFormatEnum, ESBHelper
# Configuration
client_id = "your_client_id"
client_secret = "your_client_secret"
api_code = "your_api_code"
signing_key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
esb_token_url = "https://esb.example.com/oauth/token"
esb_request_url = "https://esb.example.com/api/request"
# Prepare your data
sample_data = {
"userId": 1,
"id": 1,
"title": "Sample Title",
"body": "Sample Body"
}
# Send request to GovESB
# The library will automatically:
# 1. Get OAuth2 access token
# 2. Encrypt and sign the data
# 3. Format it with apiCode and encrypted esbBody structure
# 4. Send to GovESB
encrypted_response = ESBHelper.esb_request(
client_id=client_id,
client_secret=client_secret,
api_code=api_code,
esb_body=sample_data,
format=DataFormatEnum.JSON,
key=signing_key,
esb_token_url=esb_token_url,
esb_request_url=esb_request_url
)
print('Response from GovESB:', encrypted_response)
Note: The response from GovESB will have the same structure as the received data format shown above, with data.apiCode, data.esbBody (containing ephemeralKey, iv, encryptedData), and signature.
Creating a Response for GovESB
When you need to send a response back to GovESB:
from govesb import DataFormatEnum, ESBHelper
system_private_key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
# Your response data
response_body = '{"status": "success", "message": "Data processed"}'
# Create signed response
signed_response = ESBHelper.create_response(
esb_body=response_body,
format=DataFormatEnum.JSON,
key=system_private_key,
is_success=True,
message="Operation completed successfully"
)
print('Signed response:', signed_response)
Advanced Usage
Getting OAuth2 Access Token
The get_esb_access_token method retrieves an OAuth2 access token that is used in the Authorization header when sending requests to GovESB:
from govesb import GovESBTokenService
# Configuration
client_id = "your_client_id"
client_secret = "your_client_secret"
token_url = "https://esb.example.com/oauth/token"
# Get access token
token_response = GovESBTokenService.get_esb_access_token(
client_id=client_id,
client_secret=client_secret,
token_uri=token_url
)
if token_response.success:
access_token = token_response.access_token
print(f"Access token: {access_token}")
print(f"Token type: {token_response.token_type}")
print(f"Expires in: {token_response.expires_in} seconds")
# Use the token in Authorization header
# Authorization: Bearer {access_token}
else:
print(f"Failed to get token: {token_response.message}")
Creating Signed Requests Manually
You can create signed requests manually using create_signed_request. This is useful when you already have an access token:
from govesb import DataFormatEnum, ESBHelper, ModeOfConnection
import requests
# Configuration
api_code = "YOUR_API_CODE"
access_token = "your_access_token" # Obtained from get_esb_access_token
private_key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
esb_request_url = "https://esb.example.com/api/request"
# Prepare your data
request_body = '{"userId": 1, "action": "get_data"}'
# Create signed request
signed_request = ESBHelper.create_signed_request(
api_code=api_code,
access_token=access_token,
body=request_body,
format=DataFormatEnum.JSON,
key=private_key,
mode=ModeOfConnection.PULL # or ModeOfConnection.PUSH
)
# Send the signed request
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.post(
esb_request_url,
headers=headers,
data=signed_request.encode("utf-8")
)
print("Response:", response.text)
Signing and Verifying Data
Using RSA for Signing and Verification
from govesb import RSAHelper
import json
# Load your keys (you can also generate them)
private_key_pem = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
public_key_pem = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
# Load keys from PEM strings
private_key = RSAHelper.load_private_key_from_str(private_key_pem)
public_key = RSAHelper.load_public_key_from_str(public_key_pem)
# Data to sign
data_to_sign = '{"userId": 1, "action": "get_data"}'
# Sign the data
signature = RSAHelper.sign(
data=data_to_sign,
private_key=private_key,
algorithm="SHA256" # Options: SHA1, SHA256, SHA384, SHA512
)
print(f"Signature: {signature}")
# Verify the signature
is_valid = RSAHelper.verify(
data=data_to_sign,
signature=signature,
public_key=public_key,
algorithm="SHA256"
)
if is_valid:
print("Signature verification successful!")
else:
print("Signature verification failed!")
Using ECC for Signing and Verification
from govesb import ECC
# Private key in PEM format
private_key_pem = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
public_key_pem = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
# Data to sign
payload = '{"userId": 1, "action": "get_data"}'
# Sign the payload
signature = ECC.sign_payload(
payload=payload,
private_key_str=private_key_pem
)
print(f"ECC Signature: {signature}")
# Verify the signature
is_valid = ECC.verify_payload(
data=payload,
signature_str=signature,
public_key_str=public_key_pem
)
if is_valid:
print("ECC signature verification successful!")
else:
print("ECC signature verification failed!")
Verifying and Extracting Data (Detailed)
The verify_and_extract_data method verifies the signature and extracts the payload from received GovESB data:
from govesb import DataFormatEnum, ESBHelper
import json
# Configuration
public_key = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
# Received data from GovESB
received_data = '''
{
"data": {
"apiCode": "YOUR_API_CODE",
"esbBody": {
"ephemeralKey": "BASE64_ENCODED_EPHEMERAL_PUBLIC_KEY",
"iv": "INITIALIZATION_VECTOR",
"encryptedData": "BASE64_ENCODED_ENCRYPTED_DATA"
}
},
"signature": "BASE64_ENCODED_SIGNATURE"
}
'''
# Verify signature and extract data
response_data = ESBHelper.verify_and_extract_data(
received_data=received_data,
format=DataFormatEnum.JSON,
public_key=public_key
)
# Check verification result
if response_data.has_data:
# Parse the verified data
verified_json = json.loads(response_data.verified_data)
# Extract components
api_code = verified_json.get('data', {}).get('apiCode')
esb_body = verified_json.get('data', {}).get('esbBody')
print(f"API Code: {api_code}")
print(f"ESB Body: {esb_body}")
# Access encrypted components
ephemeral_key = esb_body.get('ephemeralKey')
iv = esb_body.get('iv')
encrypted_data = esb_body.get('encryptedData')
print(f"Ephemeral Key: {ephemeral_key}")
print(f"IV: {iv}")
print(f"Encrypted Data: {encrypted_data}")
# Process the verified data...
else:
print(f"Verification failed: {response_data.message}")
Creating Responses (Detailed)
The create_response method creates a signed response to send back to GovESB:
from govesb import DataFormatEnum, ESBHelper
import json
# Configuration
private_key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
# Prepare response data
response_data = {
"status": "success",
"result": "Data processed",
"timestamp": "2024-01-01T00:00:00Z"
}
# Convert to JSON string
response_body = json.dumps(response_data)
# Create signed response
signed_response = ESBHelper.create_response(
esb_body=response_body,
format=DataFormatEnum.JSON,
key=private_key,
is_success=True,
message="Operation completed successfully"
)
print("Signed Response:")
print(signed_response)
# The response structure will be:
# {
# "data": {
# "status": "success",
# "result": "Data processed",
# "timestamp": "2024-01-01T00:00:00Z"
# },
# "signature": "BASE64_ENCODED_SIGNATURE"
# }
Complete Workflow with Manual Steps
Here's a complete example showing all the steps manually:
from govesb import (
DataFormatEnum, ESBHelper, GovESBTokenService,
ModeOfConnection, ECC
)
import requests
import json
# Configuration
CLIENT_ID = "your_client_id"
CLIENT_SECRET = "your_client_secret"
API_CODE = "your_api_code"
PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
ESB_TOKEN_URL = "https://esb.example.com/oauth/token"
ESB_REQUEST_URL = "https://esb.example.com/api/request"
# Step 1: Get OAuth2 access token
print("Step 1: Getting access token...")
token_response = GovESBTokenService.get_esb_access_token(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
token_uri=ESB_TOKEN_URL
)
if not token_response.success:
print(f"Failed to get token: {token_response.message}")
exit(1)
access_token = token_response.access_token
print(f"✓ Access token obtained: {access_token[:20]}...")
# Step 2: Prepare request data
print("\nStep 2: Preparing request data...")
request_data = {
"userId": 1,
"action": "get_data",
"parameters": {"id": 123}
}
request_body = json.dumps(request_data)
print(f"✓ Request body prepared")
# Step 3: Create signed request
print("\nStep 3: Creating signed request...")
signed_request = ESBHelper.create_signed_request(
api_code=API_CODE,
access_token=access_token,
body=request_body,
format=DataFormatEnum.JSON,
key=PRIVATE_KEY,
mode=ModeOfConnection.PULL
)
print(f"✓ Signed request created")
# Step 4: Send request to GovESB
print("\nStep 4: Sending request to GovESB...")
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.post(
ESB_REQUEST_URL,
headers=headers,
data=signed_request.encode("utf-8")
)
print(f"✓ Response received: {response.status_code}")
# Step 5: Verify response signature
print("\nStep 5: Verifying response signature...")
response_data = ESBHelper.verify_and_extract_data(
received_data=response.text,
format=DataFormatEnum.JSON,
public_key=PUBLIC_KEY
)
if response_data.has_data:
print("✓ Signature verified successfully")
verified_json = json.loads(response_data.verified_data)
print(f"✓ Verified data: {json.dumps(verified_json, indent=2)}")
else:
print(f"✗ Signature verification failed: {response_data.message}")
# Step 6: Create response back to GovESB
print("\nStep 6: Creating response...")
response_body = json.dumps({"status": "processed", "result": "success"})
signed_response = ESBHelper.create_response(
esb_body=response_body,
format=DataFormatEnum.JSON,
key=PRIVATE_KEY,
is_success=True,
message="Data processed successfully"
)
print(f"✓ Signed response created")
API Reference
Enums
DataFormatEnum
Supported data formats:
DataFormatEnum.JSON- JSON formatDataFormatEnum.XML- XML format
ModeOfConnection
Connection modes:
ModeOfConnection.PUSH- Push modeModeOfConnection.PULL- Pull mode
Main Classes
ESBHelper
Main helper class for GovESB operations.
Methods:
-
esb_request(client_id, client_secret, api_code, esb_body, format, key, esb_token_url, esb_request_url)
Sends a signed request to GovESB. Automatically handles token acquisition.Parameters:
client_id(str): OAuth2 client IDclient_secret(str): OAuth2 client secretapi_code(str): API code for the requestesb_body(dict/str): Request body dataformat(DataFormatEnum): Data format (JSON or XML)key(str): Private key for signing (PEM format)esb_token_url(str): OAuth2 token endpoint URLesb_request_url(str): GovESB request endpoint URL
Returns: Response text from GovESB
-
verify_and_extract_data(received_data, format, public_key)
Verifies the signature of received data and extracts the payload.Parameters:
received_data(str): Received data with signatureformat(DataFormatEnum): Data format (JSON or XML)public_key(str): Public key for verification (PEM format)
Returns:
ResponseDataobject withhas_data(bool),verified_data(str), andmessage(str) -
create_response(esb_body, format, key, is_success, message)
Creates a signed response for GovESB.Parameters:
esb_body(str): Response body dataformat(DataFormatEnum): Data format (JSON or XML)key(str): Private key for signing (PEM format)is_success(bool): Whether the operation was successfulmessage(str): Response message
Returns: Signed response string
-
create_signed_request(api_code, access_token, body, format, key, mode)
Creates a signed request payload.Parameters:
api_code(str): API codeaccess_token(str): OAuth2 access tokenbody(str): Request bodyformat(DataFormatEnum): Data formatkey(str): Private key for signingmode(ModeOfConnection): Connection mode (default: PULL)
Returns: Signed request string
RSAHelper
Helper class for RSA cryptographic operations.
Methods:
generate_key_pair()- Generate RSA key pairencrypt(plain_text, public_key)- Encrypt data with RSAdecrypt(cipher_text, private_key)- Decrypt RSA encrypted datasign(data, private_key, algorithm)- Sign data with RSAverify(data, signature, public_key, algorithm)- Verify RSA signature
ECC
Helper class for Elliptic Curve Cryptography operations.
Methods:
sign_payload(payload, private_key_str)- Sign payload with ECCverify_payload(data, signature_str, public_key_str)- Verify ECC signature
GovESBTokenService
Service for managing OAuth2 tokens.
Methods:
get_esb_access_token(client_id, client_secret, token_uri)- Get OAuth2 access token
Returns: TokenResponse object with success (bool), access_token (str), and message (str)
CryptoConfig
Configuration class for cryptographic settings.
Methods:
get_ega_private_key()- Get private key fromGOVESB_PRIVATE_KEYenvironment variableget_client_public_key()- Get public key fromGOVESB_PUBLIC_KEYenvironment variableget_algorithm()- Get configured algorithm (default: "SHA256withRSA")
Configuration
Environment Variables
You can configure keys using environment variables:
export GOVESB_PRIVATE_KEY="/path/to/private_key.pem"
export GOVESB_PUBLIC_KEY="/path/to/public_key.pem"
Then use CryptoConfig to access them:
from govesb import CryptoConfig
config = CryptoConfig()
private_key = config.get_ega_private_key()
public_key = config.get_client_public_key()
Data Models
ResponseData
Response object returned by verify_and_extract_data:
has_data(bool): Whether verification was successfulverified_data(str): Extracted and verified datamessage(str): Status message
TokenResponse
Token response object:
success(bool): Whether token acquisition was successfulaccess_token(str): OAuth2 access tokenmessage(str): Status message
CryptoData
Cryptographic data container:
data: The data payloadsignature: The signature
Error Handling
The library includes comprehensive error handling:
from govesb import ESBHelper, DataFormatEnum
try:
response_data = ESBHelper.verify_and_extract_data(
received_data=data,
format=DataFormatEnum.JSON,
public_key=public_key
)
if not response_data.has_data:
print(f"Verification failed: {response_data.message}")
else:
# Process verified data
process_data(response_data.verified_data)
except Exception as e:
print(f"Error occurred: {e}")
Examples
Complete Workflow Example
from govesb import DataFormatEnum, ESBHelper, ModeOfConnection
import requests
# Configuration
CLIENT_ID = "your_client_id"
CLIENT_SECRET = "your_client_secret"
API_CODE = "your_api_code"
PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
ESB_TOKEN_URL = "https://esb.example.com/oauth/token"
ESB_REQUEST_URL = "https://esb.example.com/api/request"
# 1. Send request to GovESB
request_data = {
"action": "get_data",
"parameters": {"id": 123}
}
response = ESBHelper.esb_request(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
api_code=API_CODE,
esb_body=request_data,
format=DataFormatEnum.JSON,
key=PRIVATE_KEY,
esb_token_url=ESB_TOKEN_URL,
esb_request_url=ESB_REQUEST_URL
)
print("GovESB Response:", response)
# 2. Process received data (if applicable)
# Assuming you receive data from GovESB webhook
# The received data structure will be:
# {
# "data": {
# "apiCode": "...",
# "esbBody": {
# "ephemeralKey": "...",
# "iv": "...",
# "encryptedData": "..."
# }
# },
# "signature": "..."
# }
received_data = response # In real scenario, this comes from webhook
verified = ESBHelper.verify_and_extract_data(
received_data=received_data,
format=DataFormatEnum.JSON,
public_key=PUBLIC_KEY
)
if verified.has_data:
# Parse the verified data to access apiCode and encrypted esbBody
import json
verified_json = json.loads(verified.verified_data)
api_code = verified_json.get('data', {}).get('apiCode')
esb_body = verified_json.get('data', {}).get('esbBody')
print("API Code:", api_code)
print("Encrypted ESB Body:", esb_body)
# Note: Decrypt esbBody.encryptedData using esbBody.ephemeralKey, esbBody.iv,
# and your private key if needed for your use case
# Send response back
response_body = '{"status": "processed", "result": "success"}'
signed_response = ESBHelper.create_response(
esb_body=response_body,
format=DataFormatEnum.JSON,
key=PRIVATE_KEY,
is_success=True,
message="Data processed successfully"
)
print("Signed response:", signed_response)
Security Best Practices
- Key Management: Never hardcode private keys. Use environment variables or secure key management systems.
- HTTPS: Always use HTTPS when communicating with GovESB endpoints.
- Key Storage: Store private keys securely and restrict file permissions.
- Token Expiration: Handle token expiration and refresh tokens appropriately.
- Input Validation: Always validate and sanitize data before processing.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.
Support
For issues, questions, or contributions, please visit:
- GitHub Issues: https://github.com/LarryMatrix/govesb/issues
- Repository: https://github.com/LarryMatrix/govesb
Author
Lawrance Massanja
- Email: massanjal4@gmail.com
- GitHub: @LarryMatrix
Changelog
Version 2.1.0
- Initial release with v2 API
- Support for RSA and ECC cryptography
- JSON and XML format support
- OAuth2 token management
- Signature verification and request signing
Note: This package is designed specifically for integration with GovESB systems. Ensure you have proper credentials and API access before using this library.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file govesb-2.1.0.tar.gz.
File metadata
- Download URL: govesb-2.1.0.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5513537ac786012dfc529d96997d5835655d417a5ad7aca739316695f0a41dc0
|
|
| MD5 |
3dad80f8f81605ec945d39d0fee7dcef
|
|
| BLAKE2b-256 |
c6fa5e741eab9042ac94a750613d2c5b5ecb53eb27c4e4ef5e3e747af6ded25f
|
File details
Details for the file govesb-2.1.0-py3-none-any.whl.
File metadata
- Download URL: govesb-2.1.0-py3-none-any.whl
- Upload date:
- Size: 29.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7f61577b4f3f1d84ca419280c7692358138c50e849f19ba9bcfe38945eb8aee
|
|
| MD5 |
5d0e300e7bfc39aaa81434eff7b3df4f
|
|
| BLAKE2b-256 |
2824198b34c2b56b2aea4dab757ebd57e726c165cf98a850628cf3f75391ed36
|