A .NET implementation of GlobalPlatform Secure Channel Protocols (SCP02 and SCP03) for secure smart card communication.
- SCP02 Support: Triple DES based secure channel protocol
- SCP03 Support: AES based secure channel protocol with enhanced security
- Key Derivation: SP 800-108 compliant key derivation for SCP03
- Message Authentication: C-MAC and R-MAC support
- Encryption: Command and response data encryption
- Cross-Platform: Targets .NET 6, 7, and 8
- Well-Tested: Comprehensive unit tests with test vectors
- Fully Documented: XML documentation for IntelliSense support
dotnet add package Gp4NetOr via Package Manager:
Install-Package Gp4Netusing Gp4Net;
using Gp4Net.Domain.Keys;
using Gp4Net.Domain.Protocol;
// Create a key set with your card's static keys
var keySet = new Scp03KeySet(
keyEnc: Convert.FromHexString("404142434445464748494A4B4C4D4E4F"),
keyMac: Convert.FromHexString("404142434445464748494A4B4C4D4E4F"),
keyDek: Convert.FromHexString("404142434445464748494A4B4C4D4E4F")
);
// Create the SCP03 protocol handler
var scp03 = new Scp03Protocol(keySet);
// Initialize the secure channel
var hostChallenge = Convert.FromHexString("0102030405060708");
var initUpdateResponse = await cardReader.SendCommandAsync(
scp03.CreateInitializeUpdateCommand(hostChallenge)
);
// Process the response and establish the session
var session = scp03.ProcessInitializeUpdateResponse(initUpdateResponse);
// Authenticate
var authCommand = scp03.CreateExternalAuthenticateCommand(session, SecurityLevel.CMacAndCDecryption);
var authResponse = await cardReader.SendCommandAsync(authCommand);
// Now you can send secure commands
var secureCommand = session.WrapCommand(originalApdu);
var response = await cardReader.SendCommandAsync(secureCommand);
var unwrappedResponse = session.UnwrapResponse(response);using Gp4Net;
using Gp4Net.Domain.Keys;
using Gp4Net.Domain.Protocol;
// Create a key set with your card's static keys
var keySet = new Scp02KeySet(
keyEnc: Convert.FromHexString("404142434445464748494A4B4C4D4E4F"),
keyMac: Convert.FromHexString("404142434445464748494A4B4C4D4E4F"),
keyDek: Convert.FromHexString("404142434445464748494A4B4C4D4E4F")
);
// Create the SCP02 protocol handler
var scp02 = new Scp02Protocol(keySet);
// Similar flow as SCP03...The library is organized into several key components:
- Cryptography: Low-level cryptographic operations (AES, DES, CMAC, padding)
- Domain: Core domain models (commands, keys, sessions, protocols)
- Interfaces: Abstractions for extensibility
- Utils: Helper methods and extensions
- Always use secure random number generators for challenges
- Protect your static keys appropriately
- Use the highest security level supported by your card
- Implement proper session management and cleanup
- Follow GlobalPlatform best practices for production deployments
Contributions are welcome! Please read our contributing guidelines and ensure:
- Code follows .NET naming conventions
- All public APIs are documented
- Unit tests are provided for new functionality
- No compiler warnings
This project is licensed under the MIT License - see the LICENSE file for details.
- GlobalPlatform Card Specification v2.3
- NIST SP 800-108: Recommendation for Key Derivation Using Pseudorandom Functions
- NIST SP 800-38A/B: Block Cipher Modes of Operation
- SCP03 KDF test vectors from blaufish/scp03_kdf_testvectors
For questions and support:
- Open an issue on GitHub
- Check the documentation and examples
- Review the unit tests for usage patterns