Skip to content

Commit

Permalink
add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanTsisyk committed Dec 29, 2024
1 parent 199f59a commit 147b4a6
Show file tree
Hide file tree
Showing 185 changed files with 19,603 additions and 153 deletions.
10 changes: 10 additions & 0 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/other.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 20 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# **CryptoKit**

![Purpose](https://img.shields.io/badge/purpose-cryptographic%20library-blue)
![Status](https://img.shields.io/badge/status-active-brightgreen)
![Last Commit](https://img.shields.io/github/last-commit/RomanTsisyk/CryptoKit)
![Docs](https://img.shields.io/badge/docs-up--to--date-brightgreen)
![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/1/badge)
[![Known Vulnerabilities](https://snyk.io/test/github/RomanTsisyk/CryptoKit/badge.svg)](https://snyk.io/test/github/RomanTsisyk/CryptoKit)

![Status](https://img.shields.io/badge/status-active-brightgreen)
![Last Commit](https://img.shields.io/github/last-commit/RomanTsisyk/CryptoKit)
![GitHub stars](https://img.shields.io/github/stars/RomanTsisyk/CryptoKit?style=social)
![Contributors](https://img.shields.io/github/contributors/RomanTsisyk/CryptoKit)

Expand All @@ -23,23 +24,28 @@

---

## **Documentation**
Explore the detailed documentation on the [CryptoKit Wiki](https://github.com/RomanTsisyk/CryptoKit/wiki):
## CryptoLib Documentation

CryptoLib provides a comprehensive set of cryptographic operations, and with this release, we have also generated full API documentation to help developers integrate it into their projects seamlessly.

1. **[AES Encryption and Decryption](https://github.com/RomanTsisyk/CryptoKit/wiki/01-AES-Encryption-and-Decryption)**
Secure your data using AES-GCM with Base64 encoding.
The documentation covers the following:

2. **[RSA Encryption and Decryption](https://github.com/RomanTsisyk/CryptoKit/wiki/02.-RSA-Encryption-and-Decryption)**
Encrypt small payloads with RSA-OAEP for secure communication.
- **Key Management**: Generate, retrieve, and delete keys securely from the Keystore.
- **Cryptographic Operations**: Encrypt, decrypt, and sign data with ease.
- **Error Handling**: Detailed error messages and exception handling tailored to cryptographic operations.
- **Usage Examples**: Simple, easy-to-follow examples to get started quickly.

3. **[Digital Signatures](https://github.com/RomanTsisyk/CryptoKit/wiki/03.-Digital-Signatures)**
Sign and verify data for integrity and authenticity.
You can access the full documentation [here](link_to_your_docs), which includes:

4. **[QR Code Integration](https://github.com/RomanTsisyk/CryptoKit/wiki/04.-QR-Code-Integration)**
Generate and decode secure QR codes for data handling.
- Function and method signatures
- Descriptions of parameters and return values
- Exception handling details
- Code examples for various use cases

5. **[Key Management](https://github.com/RomanTsisyk/CryptoKit/wiki/05.-Key-Management)**
Manage, store, and rotate cryptographic keys seamlessly.
## 🚀 Get Started

1. Clone this repository.
2. Check out the `docs/` folder for local documentation.
3. Refer to the API docs for in-depth technical details on each class and method.

---
10 changes: 5 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.library") version "8.5.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}
plugins {
id("com.android.library") version "8.5.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
id("org.jetbrains.dokka") version "2.0.0"
}
2 changes: 2 additions & 0 deletions cryptolib/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.dokka")
}

android {
Expand Down Expand Up @@ -69,3 +70,4 @@ dependencies {
androidTestImplementation ("androidx.test:core:1.6.1")

}

Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import javax.crypto.Cipher
class BiometricHelper(private val context: Context) {

/**
* Authenticates the user using biometrics and optionally decrypts the provided encrypted data.
* Authenticates the user using biometric data (e.g., fingerprint) and optionally decrypts encrypted data after successful authentication.
* Provides success and error callbacks for handling decryption and authentication results.
*
* @param activity The activity where the biometric prompt will be displayed.
* @param encryptedData Data to be decrypted upon successful authentication.
* @param encryptedData The encrypted data to be decrypted upon successful authentication.
* @param title The title displayed on the biometric prompt.
* @param description The description displayed on the biometric prompt.
* @param onSuccess Callback to handle the decrypted data.
* @param onError Callback to handle errors during authentication or decryption.
* @param onAuthenticationError Callback to handle authentication-specific errors.
* @param onSuccess Callback invoked with decrypted data on successful authentication.
* @param onError Callback invoked if any error occurs during decryption or authentication.
* @param onAuthenticationError Callback invoked on authentication errors (e.g., failed fingerprint scan).
*/
fun authenticate(
activity: FragmentActivity,
Expand All @@ -30,7 +32,6 @@ class BiometricHelper(private val context: Context) {
.setTitle(title)
.setDescription(description)
.setSubtitle("Log in using your biometrics")
.setDescription("Place your fingerprint on the sensor to authenticate")
.setNegativeButtonText("Cancel")
.build()

Expand All @@ -49,56 +50,60 @@ class BiometricHelper(private val context: Context) {
)
}
if (decryptedData != null) {
onSuccess(decryptedData)
onSuccess(decryptedData) // Handle success
} else {
onError(Exception("Decryption returned null"))
onError(Exception("Decryption returned null")) // Handle decryption failure
}
} catch (e: Exception) {
onError(e)
onError(e) // Handle exception
}
}

override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
onAuthenticationError(errorCode, errString)
onAuthenticationError(errorCode, errString) // Handle authentication error
}

override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
onError(Exception("Authentication failed"))
onError(Exception("Authentication failed")) // Handle failed authentication
}
}
)

val cipher = getCipher()
val cipher = getCipher() // Initialize cipher for decryption
val cryptoObject = BiometricPrompt.CryptoObject(cipher)

biometricPrompt.authenticate(promptInfo, cryptoObject)
biometricPrompt.authenticate(promptInfo, cryptoObject) // Start authentication
}

/**
* Initializes a Cipher object for decryption.
* @return A Cipher initialized with a secret key.
* Initializes a Cipher object for AES decryption.
* The cipher is initialized with the secure key and is used to decrypt data.
*
* @return A Cipher initialized in DECRYPT_MODE.
* @throws IllegalStateException if initialization fails.
*/
private fun getCipher(): Cipher {
return try {
val secretKey = KeyHelper.getKey() // Retrieve the secure key from KeyHelper
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, secretKey)
val cipher = Cipher.getInstance("AES/GCM/NoPadding") // AES GCM mode
cipher.init(Cipher.DECRYPT_MODE, secretKey) // Initialize cipher for decryption
cipher
} catch (e: Exception) {
throw IllegalStateException("Failed to initialize Cipher", e)
throw IllegalStateException("Failed to initialize Cipher", e) // Handle initialization failure
}
}

/**
* Decrypts the provided data using the Cipher.
* Decrypts the provided encrypted data using the specified Cipher.
* This method is invoked as part of the decryption process after successful authentication.
*
* @param cipher The Cipher used for decryption.
* @param encryptedData The encrypted data to decrypt.
* @return The decrypted data as a ByteArray.
*/
private fun decryptData(cipher: Cipher, encryptedData: ByteArray): ByteArray {
return cipher.doFinal(encryptedData)
return cipher.doFinal(encryptedData) // Perform decryption
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,66 @@ import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.GCMParameterSpec

/**
* Object responsible for AES encryption and decryption operations using the AES-GCM algorithm.
* Provides methods for encrypting and decrypting data, as well as generating AES keys.
*/
object AESEncryption {

private const val TRANSFORMATION = "AES/GCM/NoPadding"
private const val IV_SIZE = 12 // Recommended IV size for GCM
private const val TAG_SIZE = 128
private const val KEY_SIZE = 256
private const val TRANSFORMATION = "AES/GCM/NoPadding" // AES-GCM algorithm transformation
private const val IV_SIZE = 12 // Recommended IV size for GCM mode
private const val TAG_SIZE = 128 // Tag size for GCM mode (in bits)
private const val KEY_SIZE = 256 // Key size (in bits)

/**
* Encrypts plaintext using AES-GCM.
* Throws CryptoOperationException on failure.
* Encrypts the provided plaintext using AES-GCM encryption.
*
* @param plaintext The data to be encrypted in ByteArray format.
* @param key The AES SecretKey used for encryption.
* @return A Base64-encoded string containing the IV and the ciphertext.
* @throws CryptoOperationException if the encryption process fails.
*/
fun encrypt(plaintext: ByteArray, key: SecretKey): String {
return try {
val cipher = Cipher.getInstance(TRANSFORMATION)

// Generate a random IV
// Generate a random IV (Initialization Vector)
val iv = ByteArray(IV_SIZE)
SecureRandom().nextBytes(iv)
val spec = GCMParameterSpec(TAG_SIZE, iv)

// Initialize the cipher for encryption and perform the encryption
cipher.init(Cipher.ENCRYPT_MODE, key, spec)
val ciphertext = cipher.doFinal(plaintext)

// Prepend IV to ciphertext
// Prepend IV to ciphertext for later use in decryption
val encrypted = iv + ciphertext

// Return as Base64 string
// Return the encrypted data as a Base64 string
Base64.getEncoder().encodeToString(encrypted)
} catch (e: Exception) {
throw CryptoOperationException("Encryption", e)
}
}

/**
* Decrypts ciphertext using AES-GCM.
* Throws CryptoOperationException on failure.
* Decrypts the provided Base64-encoded encrypted data using AES-GCM decryption.
*
* @param encryptedData A Base64-encoded string containing the IV and the ciphertext.
* @param key The AES SecretKey used for decryption.
* @return The decrypted data as a ByteArray.
* @throws CryptoOperationException if the decryption process fails.
*/
fun decrypt(encryptedData: String, key: SecretKey): ByteArray {
return try {
val encryptedBytes = Base64.getDecoder().decode(encryptedData)

// Extract IV and ciphertext
// Extract IV and ciphertext from the encrypted data
val iv = encryptedBytes.copyOfRange(0, IV_SIZE)
val ciphertext = encryptedBytes.copyOfRange(IV_SIZE, encryptedBytes.size)
val spec = GCMParameterSpec(TAG_SIZE, iv)

// Initialize the cipher for decryption and perform the decryption
val cipher = Cipher.getInstance(TRANSFORMATION)
cipher.init(Cipher.DECRYPT_MODE, key, spec)
cipher.doFinal(ciphertext)
Expand All @@ -63,7 +77,9 @@ object AESEncryption {
}

/**
* Generates a new AES key.
* Generates a new AES key with the specified key size.
*
* @return A newly generated AES SecretKey.
*/
fun generateKey(): SecretKey {
val keyGenerator = KeyGenerator.getInstance("AES")
Expand Down
Loading

0 comments on commit 147b4a6

Please sign in to comment.