Guest User

Untitled

a guest
Feb 13th, 2025
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.69 KB | None | 0 0
  1. Here's a step-by-step guide to encrypting and decrypting a string using Windows CNG with RSA 4096 in PureBasic:
  2.  
  3. ```purebasic
  4. ; RSA 4096 Encryption/Decryption using Windows CNG in PureBasic
  5.  
  6. ; Constants
  7. #STATUS_SUCCESS = $00000000
  8. #BCRYPT_RSAPUBLIC_BLOB = "RSAPUBLICBLOB"
  9. #BCRYPT_PAD_PKCS1 = 2
  10.  
  11. ; Prototypes for BCrypt functions
  12. Prototype.l BCryptOpenAlgorithmProvider(phAlgorithm, pszAlgId.p-unicode, pszImplementation.p-unicode, dwFlags.l)
  13. Prototype.l BCryptGenerateKeyPair(hAlgorithm, phKey, dwLength.l, dwFlags.l)
  14. Prototype.l BCryptFinalizeKeyPair(hKey, dwFlags.l)
  15. Prototype.l BCryptExportKey(hKey, hExportKey, pszBlobType.p-unicode, pbOutput, cbOutput.l, pcbResult, dwFlags.l)
  16. Prototype.l BCryptImportKey(hAlgorithm, hImportKey, pszBlobType.p-unicode, phKey, pbKeyObject, cbKeyObject.l, pbInput, cbInput.l, dwFlags.l)
  17. Prototype.l BCryptEncrypt(hKey, pbInput, cbInput.l, pPaddingInfo, pbIV, cbIV.l, pbOutput, cbOutput.l, pcbResult, dwFlags.l)
  18. Prototype.l BCryptDecrypt(hKey, pbInput, cbInput.l, pPaddingInfo, pbIV, cbIV.l, pbOutput, cbOutput.l, pcbResult, dwFlags.l)
  19. Prototype.l BCryptCloseAlgorithmProvider(hAlgorithm, dwFlags.l)
  20. Prototype.l BCryptDestroyKey(hKey)
  21.  
  22. ; Load BCrypt library and functions
  23. Global hBCrypt = OpenLibrary(#PB_Any, "bcrypt.dll")
  24. If Not hBCrypt
  25. MessageRequester("Error", "Failed to load bcrypt.dll")
  26. End
  27. EndIf
  28.  
  29. Global BCryptOpenAlgorithmProvider.BCryptOpenAlgorithmProvider = GetFunction(hBCrypt, "BCryptOpenAlgorithmProvider")
  30. Global BCryptGenerateKeyPair.BCryptGenerateKeyPair = GetFunction(hBCrypt, "BCryptGenerateKeyPair")
  31. Global BCryptFinalizeKeyPair.BCryptFinalizeKeyPair = GetFunction(hBCrypt, "BCryptFinalizeKeyPair")
  32. Global BCryptExportKey.BCryptExportKey = GetFunction(hBCrypt, "BCryptExportKey")
  33. Global BCryptImportKey.BCryptImportKey = GetFunction(hBCrypt, "BCryptImportKey")
  34. Global BCryptEncrypt.BCryptEncrypt = GetFunction(hBCrypt, "BCryptEncrypt")
  35. Global BCryptDecrypt.BCryptDecrypt = GetFunction(hBCrypt, "BCryptDecrypt")
  36. Global BCryptCloseAlgorithmProvider.BCryptCloseAlgorithmProvider = GetFunction(hBCrypt, "BCryptCloseAlgorithmProvider")
  37. Global BCryptDestroyKey.BCryptDestroyKey = GetFunction(hBCrypt, "BCryptDestroyKey")
  38.  
  39. ; Validate all functions loaded
  40. If Not BCryptOpenAlgorithmProvider Or Not BCryptGenerateKeyPair Or Not BCryptFinalizeKeyPair Or
  41. Not BCryptExportKey Or Not BCryptImportKey Or Not BCryptEncrypt Or Not BCryptDecrypt Or
  42. Not BCryptCloseAlgorithmProvider Or Not BCryptDestroyKey
  43. MessageRequester("Error", "Failed to load BCrypt functions")
  44. End
  45. EndIf
  46.  
  47. ; Main process
  48. Procedure Main()
  49. ; Initialize variables
  50. Protected hAlg, hKey, hPublicKey, result.l, publicKeySize.l, *publicKeyBlob
  51. Protected plainText$, plainSize.l, *plainData, encryptedSize.l, *encryptedData
  52. Protected decryptedSize.l, *decryptedData, decryptedText$
  53.  
  54. ; 1. Open RSA algorithm provider
  55. result = BCryptOpenAlgorithmProvider(@hAlg, "RSA", #Null$, 0)
  56. If result <> #STATUS_SUCCESS
  57. MessageRequester("Error", "BCryptOpenAlgorithmProvider failed: " + Hex(result))
  58. ProcedureReturn
  59. EndIf
  60.  
  61. ; 2. Generate 4096-bit RSA key pair
  62. result = BCryptGenerateKeyPair(hAlg, @hKey, 4096, 0)
  63. If result <> #STATUS_SUCCESS
  64. MessageRequester("Error", "BCryptGenerateKeyPair failed: " + Hex(result))
  65. BCryptCloseAlgorithmProvider(hAlg, 0)
  66. ProcedureReturn
  67. EndIf
  68.  
  69. ; 3. Finalize key pair
  70. result = BCryptFinalizeKeyPair(hKey, 0)
  71. If result <> #STATUS_SUCCESS
  72. MessageRequester("Error", "BCryptFinalizeKeyPair failed: " + Hex(result))
  73. BCryptDestroyKey(hKey)
  74. BCryptCloseAlgorithmProvider(hAlg, 0)
  75. ProcedureReturn
  76. EndIf
  77.  
  78. ; 4. Export public key
  79. result = BCryptExportKey(hKey, 0, #BCRYPT_RSAPUBLIC_BLOB, 0, 0, @publicKeySize, 0)
  80. If result <> #STATUS_SUCCESS
  81. MessageRequester("Error", "BCryptExportKey (size) failed: " + Hex(result))
  82. BCryptDestroyKey(hKey)
  83. BCryptCloseAlgorithmProvider(hAlg, 0)
  84. ProcedureReturn
  85. EndIf
  86.  
  87. *publicKeyBlob = AllocateMemory(publicKeySize)
  88. result = BCryptExportKey(hKey, 0, #BCRYPT_RSAPUBLIC_BLOB, *publicKeyBlob, publicKeySize, @publicKeySize, 0)
  89. If result <> #STATUS_SUCCESS
  90. MessageRequester("Error", "BCryptExportKey failed: " + Hex(result))
  91. FreeMemory(*publicKeyBlob)
  92. BCryptDestroyKey(hKey)
  93. BCryptCloseAlgorithmProvider(hAlg, 0)
  94. ProcedureReturn
  95. EndIf
  96.  
  97. ; 5. Import public key
  98. result = BCryptImportKey(hAlg, 0, #BCRYPT_RSAPUBLIC_BLOB, @hPublicKey, 0, 0, *publicKeyBlob, publicKeySize, 0)
  99. FreeMemory(*publicKeyBlob)
  100. If result <> #STATUS_SUCCESS
  101. MessageRequester("Error", "BCryptImportKey failed: " + Hex(result))
  102. BCryptDestroyKey(hKey)
  103. BCryptCloseAlgorithmProvider(hAlg, 0)
  104. ProcedureReturn
  105. EndIf
  106.  
  107. ; Prepare plaintext
  108. plainText$ = "Hello World! This is a secret message."
  109. plainSize = StringByteLength(plainText$, #PB_UTF8)
  110. *plainData = AllocateMemory(plainSize)
  111. PokeS(*plainData, plainText$, -1, #PB_UTF8)
  112.  
  113. ; 6. Encrypt data
  114. result = BCryptEncrypt(hPublicKey, *plainData, plainSize, 0, 0, 0, 0, 0, @encryptedSize, #BCRYPT_PAD_PKCS1)
  115. If result <> #STATUS_SUCCESS
  116. MessageRequester("Error", "BCryptEncrypt (size) failed: " + Hex(result))
  117. FreeMemory(*plainData)
  118. BCryptDestroyKey(hPublicKey)
  119. BCryptDestroyKey(hKey)
  120. BCryptCloseAlgorithmProvider(hAlg, 0)
  121. ProcedureReturn
  122. EndIf
  123.  
  124. *encryptedData = AllocateMemory(encryptedSize)
  125. result = BCryptEncrypt(hPublicKey, *plainData, plainSize, 0, 0, 0, *encryptedData, encryptedSize, @encryptedSize, #BCRYPT_PAD_PKCS1)
  126. FreeMemory(*plainData)
  127. If result <> #STATUS_SUCCESS
  128. MessageRequester("Error", "BCryptEncrypt failed: " + Hex(result))
  129. FreeMemory(*encryptedData)
  130. BCryptDestroyKey(hPublicKey)
  131. BCryptDestroyKey(hKey)
  132. BCryptCloseAlgorithmProvider(hAlg, 0)
  133. ProcedureReturn
  134. EndIf
  135.  
  136. ; 7. Decrypt data
  137. result = BCryptDecrypt(hKey, *encryptedData, encryptedSize, 0, 0, 0, 0, 0, @decryptedSize, #BCRYPT_PAD_PKCS1)
  138. If result <> #STATUS_SUCCESS
  139. MessageRequester("Error", "BCryptDecrypt (size) failed: " + Hex(result))
  140. FreeMemory(*encryptedData)
  141. BCryptDestroyKey(hPublicKey)
  142. BCryptDestroyKey(hKey)
  143. BCryptCloseAlgorithmProvider(hAlg, 0)
  144. ProcedureReturn
  145. EndIf
  146.  
  147. *decryptedData = AllocateMemory(decryptedSize)
  148. result = BCryptDecrypt(hKey, *encryptedData, encryptedSize, 0, 0, 0, *decryptedData, decryptedSize, @decryptedSize, #BCRYPT_PAD_PKCS1)
  149. FreeMemory(*encryptedData)
  150. If result <> #STATUS_SUCCESS
  151. MessageRequester("Error", "BCryptDecrypt failed: " + Hex(result))
  152. FreeMemory(*decryptedData)
  153. BCryptDestroyKey(hPublicKey)
  154. BCryptDestroyKey(hKey)
  155. BCryptCloseAlgorithmProvider(hAlg, 0)
  156. ProcedureReturn
  157. EndIf
  158.  
  159. ; Show results
  160. decryptedText$ = PeekS(*decryptedData, decryptedSize, #PB_UTF8)
  161. MessageRequester("Success", "Decrypted text: " + decryptedText$)
  162.  
  163. ; Cleanup
  164. FreeMemory(*decryptedData)
  165. BCryptDestroyKey(hPublicKey)
  166. BCryptDestroyKey(hKey)
  167. BCryptCloseAlgorithmProvider(hAlg, 0)
  168. EndProcedure
  169.  
  170. Main()
  171. CloseLibrary(hBCrypt)
  172. ```
  173.  
  174. This code:
  175. 1. Loads the Windows CNG library (bcrypt.dll)
  176. 2. Creates an RSA 4096-bit key pair
  177. 3. Exports/imports the public key for encryption
  178. 4. Encrypts a sample string using RSA-OAEP padding
  179. 5. Decrypts the message using the private key
  180. 6. Properly cleans up all resources
  181.  
  182. Key points:
  183. - Uses PKCS#1 v1.5 padding for compatibility
  184. - Handles memory allocation and cleanup properly
  185. - Includes error checking for all cryptographic operations
  186. - Converts strings to/from UTF-8 for proper byte handling
  187.  
  188. Note: For production use, consider adding:
  189. - More robust error handling
  190. - Secure memory wiping for sensitive data
  191. - Proper key storage mechanisms
  192. - Input validation
  193. - OAEP padding for better security
Advertisement
Add Comment
Please, Sign In to add comment