Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Here's a step-by-step guide to encrypting and decrypting a string using Windows CNG with RSA 4096 in PureBasic:
- ```purebasic
- ; RSA 4096 Encryption/Decryption using Windows CNG in PureBasic
- ; Constants
- #STATUS_SUCCESS = $00000000
- #BCRYPT_RSAPUBLIC_BLOB = "RSAPUBLICBLOB"
- #BCRYPT_PAD_PKCS1 = 2
- ; Prototypes for BCrypt functions
- Prototype.l BCryptOpenAlgorithmProvider(phAlgorithm, pszAlgId.p-unicode, pszImplementation.p-unicode, dwFlags.l)
- Prototype.l BCryptGenerateKeyPair(hAlgorithm, phKey, dwLength.l, dwFlags.l)
- Prototype.l BCryptFinalizeKeyPair(hKey, dwFlags.l)
- Prototype.l BCryptExportKey(hKey, hExportKey, pszBlobType.p-unicode, pbOutput, cbOutput.l, pcbResult, dwFlags.l)
- Prototype.l BCryptImportKey(hAlgorithm, hImportKey, pszBlobType.p-unicode, phKey, pbKeyObject, cbKeyObject.l, pbInput, cbInput.l, dwFlags.l)
- Prototype.l BCryptEncrypt(hKey, pbInput, cbInput.l, pPaddingInfo, pbIV, cbIV.l, pbOutput, cbOutput.l, pcbResult, dwFlags.l)
- Prototype.l BCryptDecrypt(hKey, pbInput, cbInput.l, pPaddingInfo, pbIV, cbIV.l, pbOutput, cbOutput.l, pcbResult, dwFlags.l)
- Prototype.l BCryptCloseAlgorithmProvider(hAlgorithm, dwFlags.l)
- Prototype.l BCryptDestroyKey(hKey)
- ; Load BCrypt library and functions
- Global hBCrypt = OpenLibrary(#PB_Any, "bcrypt.dll")
- If Not hBCrypt
- MessageRequester("Error", "Failed to load bcrypt.dll")
- End
- EndIf
- Global BCryptOpenAlgorithmProvider.BCryptOpenAlgorithmProvider = GetFunction(hBCrypt, "BCryptOpenAlgorithmProvider")
- Global BCryptGenerateKeyPair.BCryptGenerateKeyPair = GetFunction(hBCrypt, "BCryptGenerateKeyPair")
- Global BCryptFinalizeKeyPair.BCryptFinalizeKeyPair = GetFunction(hBCrypt, "BCryptFinalizeKeyPair")
- Global BCryptExportKey.BCryptExportKey = GetFunction(hBCrypt, "BCryptExportKey")
- Global BCryptImportKey.BCryptImportKey = GetFunction(hBCrypt, "BCryptImportKey")
- Global BCryptEncrypt.BCryptEncrypt = GetFunction(hBCrypt, "BCryptEncrypt")
- Global BCryptDecrypt.BCryptDecrypt = GetFunction(hBCrypt, "BCryptDecrypt")
- Global BCryptCloseAlgorithmProvider.BCryptCloseAlgorithmProvider = GetFunction(hBCrypt, "BCryptCloseAlgorithmProvider")
- Global BCryptDestroyKey.BCryptDestroyKey = GetFunction(hBCrypt, "BCryptDestroyKey")
- ; Validate all functions loaded
- If Not BCryptOpenAlgorithmProvider Or Not BCryptGenerateKeyPair Or Not BCryptFinalizeKeyPair Or
- Not BCryptExportKey Or Not BCryptImportKey Or Not BCryptEncrypt Or Not BCryptDecrypt Or
- Not BCryptCloseAlgorithmProvider Or Not BCryptDestroyKey
- MessageRequester("Error", "Failed to load BCrypt functions")
- End
- EndIf
- ; Main process
- Procedure Main()
- ; Initialize variables
- Protected hAlg, hKey, hPublicKey, result.l, publicKeySize.l, *publicKeyBlob
- Protected plainText$, plainSize.l, *plainData, encryptedSize.l, *encryptedData
- Protected decryptedSize.l, *decryptedData, decryptedText$
- ; 1. Open RSA algorithm provider
- result = BCryptOpenAlgorithmProvider(@hAlg, "RSA", #Null$, 0)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptOpenAlgorithmProvider failed: " + Hex(result))
- ProcedureReturn
- EndIf
- ; 2. Generate 4096-bit RSA key pair
- result = BCryptGenerateKeyPair(hAlg, @hKey, 4096, 0)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptGenerateKeyPair failed: " + Hex(result))
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- ; 3. Finalize key pair
- result = BCryptFinalizeKeyPair(hKey, 0)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptFinalizeKeyPair failed: " + Hex(result))
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- ; 4. Export public key
- result = BCryptExportKey(hKey, 0, #BCRYPT_RSAPUBLIC_BLOB, 0, 0, @publicKeySize, 0)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptExportKey (size) failed: " + Hex(result))
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- *publicKeyBlob = AllocateMemory(publicKeySize)
- result = BCryptExportKey(hKey, 0, #BCRYPT_RSAPUBLIC_BLOB, *publicKeyBlob, publicKeySize, @publicKeySize, 0)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptExportKey failed: " + Hex(result))
- FreeMemory(*publicKeyBlob)
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- ; 5. Import public key
- result = BCryptImportKey(hAlg, 0, #BCRYPT_RSAPUBLIC_BLOB, @hPublicKey, 0, 0, *publicKeyBlob, publicKeySize, 0)
- FreeMemory(*publicKeyBlob)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptImportKey failed: " + Hex(result))
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- ; Prepare plaintext
- plainText$ = "Hello World! This is a secret message."
- plainSize = StringByteLength(plainText$, #PB_UTF8)
- *plainData = AllocateMemory(plainSize)
- PokeS(*plainData, plainText$, -1, #PB_UTF8)
- ; 6. Encrypt data
- result = BCryptEncrypt(hPublicKey, *plainData, plainSize, 0, 0, 0, 0, 0, @encryptedSize, #BCRYPT_PAD_PKCS1)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptEncrypt (size) failed: " + Hex(result))
- FreeMemory(*plainData)
- BCryptDestroyKey(hPublicKey)
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- *encryptedData = AllocateMemory(encryptedSize)
- result = BCryptEncrypt(hPublicKey, *plainData, plainSize, 0, 0, 0, *encryptedData, encryptedSize, @encryptedSize, #BCRYPT_PAD_PKCS1)
- FreeMemory(*plainData)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptEncrypt failed: " + Hex(result))
- FreeMemory(*encryptedData)
- BCryptDestroyKey(hPublicKey)
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- ; 7. Decrypt data
- result = BCryptDecrypt(hKey, *encryptedData, encryptedSize, 0, 0, 0, 0, 0, @decryptedSize, #BCRYPT_PAD_PKCS1)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptDecrypt (size) failed: " + Hex(result))
- FreeMemory(*encryptedData)
- BCryptDestroyKey(hPublicKey)
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- *decryptedData = AllocateMemory(decryptedSize)
- result = BCryptDecrypt(hKey, *encryptedData, encryptedSize, 0, 0, 0, *decryptedData, decryptedSize, @decryptedSize, #BCRYPT_PAD_PKCS1)
- FreeMemory(*encryptedData)
- If result <> #STATUS_SUCCESS
- MessageRequester("Error", "BCryptDecrypt failed: " + Hex(result))
- FreeMemory(*decryptedData)
- BCryptDestroyKey(hPublicKey)
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- ProcedureReturn
- EndIf
- ; Show results
- decryptedText$ = PeekS(*decryptedData, decryptedSize, #PB_UTF8)
- MessageRequester("Success", "Decrypted text: " + decryptedText$)
- ; Cleanup
- FreeMemory(*decryptedData)
- BCryptDestroyKey(hPublicKey)
- BCryptDestroyKey(hKey)
- BCryptCloseAlgorithmProvider(hAlg, 0)
- EndProcedure
- Main()
- CloseLibrary(hBCrypt)
- ```
- This code:
- 1. Loads the Windows CNG library (bcrypt.dll)
- 2. Creates an RSA 4096-bit key pair
- 3. Exports/imports the public key for encryption
- 4. Encrypts a sample string using RSA-OAEP padding
- 5. Decrypts the message using the private key
- 6. Properly cleans up all resources
- Key points:
- - Uses PKCS#1 v1.5 padding for compatibility
- - Handles memory allocation and cleanup properly
- - Includes error checking for all cryptographic operations
- - Converts strings to/from UTF-8 for proper byte handling
- Note: For production use, consider adding:
- - More robust error handling
- - Secure memory wiping for sensitive data
- - Proper key storage mechanisms
- - Input validation
- - OAEP padding for better security
Advertisement
Add Comment
Please, Sign In to add comment