or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-tools.mdcrypto-operations.mdindex.mdkey-management.md

crypto-operations.mddocs/

0

# Cryptographic Operations

1

2

PKCS#1 v1.5 encryption, decryption, signing, and signature verification operations with support for multiple hash algorithms and secure cryptographic practices.

3

4

## Capabilities

5

6

### Message Encryption

7

8

Encrypt messages using RSA public key cryptography with PKCS#1 v1.5 padding.

9

10

```python { .api }

11

def encrypt(message: bytes, pub_key: PublicKey) -> bytes:

12

"""

13

Encrypts the given message using PKCS#1 v1.5.

14

15

Parameters:

16

- message: bytes - the message to encrypt (max length: k-11 bytes where k is key size in bytes)

17

- pub_key: PublicKey - the public key to encrypt with

18

19

Returns:

20

bytes - encrypted message as bytes

21

22

Raises:

23

- OverflowError: when the message is too large for the key size

24

"""

25

```

26

27

**Usage Example:**

28

29

```python

30

import rsa

31

32

# Generate keys

33

(public_key, private_key) = rsa.newkeys(2048)

34

35

# Encrypt a message

36

message = b'Hello, World!'

37

encrypted = rsa.encrypt(message, public_key)

38

39

# Encrypted data is the same length as the key

40

print(f"Encrypted length: {len(encrypted)} bytes")

41

```

42

43

### Message Decryption

44

45

Decrypt messages that were encrypted with the corresponding public key.

46

47

```python { .api }

48

def decrypt(crypto: bytes, priv_key: PrivateKey) -> bytes:

49

"""

50

Decrypts the given message using PKCS#1 v1.5.

51

52

Parameters:

53

- crypto: bytes - encrypted message to decrypt

54

- priv_key: PrivateKey - the private key to decrypt with

55

56

Returns:

57

bytes - decrypted message as bytes

58

59

Raises:

60

- DecryptionError: when decryption fails (wrong key, corrupted data, etc.)

61

"""

62

```

63

64

**Usage Example:**

65

66

```python

67

import rsa

68

69

# Decrypt the message

70

try:

71

decrypted = rsa.decrypt(encrypted, private_key)

72

print(decrypted.decode('utf-8')) # Convert bytes to string

73

except rsa.DecryptionError:

74

print("Decryption failed - wrong key or corrupted data")

75

```

76

77

### Message Signing

78

79

Create digital signatures for messages using RSA private keys with various hash algorithms.

80

81

```python { .api }

82

def sign(message: bytes, priv_key: PrivateKey, hash_method: str) -> bytes:

83

"""

84

Signs a message using the private key.

85

86

Parameters:

87

- message: bytes - the message to sign

88

- priv_key: PrivateKey - the private key to sign with

89

- hash_method: str - hash algorithm ('SHA-1', 'SHA-224', 'SHA-256', 'SHA-384', 'SHA-512', 'MD5')

90

91

Returns:

92

bytes - signature as bytes

93

94

Raises:

95

- ValueError: for unsupported hash methods

96

"""

97

98

def sign_hash(hash_value: bytes, priv_key: PrivateKey, hash_method: str) -> bytes:

99

"""

100

Signs a pre-computed hash value.

101

102

Parameters:

103

- hash_value: bytes - the hash to sign (must match hash_method)

104

- priv_key: PrivateKey - the private key to sign with

105

- hash_method: str - hash algorithm used to create hash_value

106

107

Returns:

108

bytes - signature as bytes

109

"""

110

```

111

112

**Usage Example:**

113

114

```python

115

import rsa

116

117

# Sign a message

118

message = b'Important document content'

119

signature = rsa.sign(message, private_key, 'SHA-256')

120

121

# Sign a pre-computed hash

122

import hashlib

123

hash_obj = hashlib.sha256(message)

124

hash_bytes = hash_obj.digest()

125

signature = rsa.sign_hash(hash_bytes, private_key, 'SHA-256')

126

```

127

128

### Signature Verification

129

130

Verify digital signatures to ensure message authenticity and integrity.

131

132

```python { .api }

133

def verify(message: bytes, signature: bytes, pub_key: PublicKey) -> str:

134

"""

135

Verifies a message signature.

136

137

Parameters:

138

- message: bytes - the original message

139

- signature: bytes - the signature to verify

140

- pub_key: PublicKey - the public key to verify with

141

142

Returns:

143

str - the hash method used for signing ('SHA-256', etc.)

144

145

Raises:

146

- VerificationError: when signature verification fails

147

"""

148

149

def find_signature_hash(signature: bytes, pub_key: PublicKey) -> str:

150

"""

151

Finds the hash method used in a signature.

152

153

Parameters:

154

- signature: bytes - the signature to analyze

155

- pub_key: PublicKey - the public key used for verification

156

157

Returns:

158

str - the hash method name ('SHA-256', etc.)

159

160

Raises:

161

- VerificationError: when signature cannot be processed

162

"""

163

```

164

165

**Usage Example:**

166

167

```python

168

import rsa

169

170

# Verify a signature

171

try:

172

hash_method = rsa.verify(message, signature, public_key)

173

print(f"Signature valid - signed with {hash_method}")

174

except rsa.VerificationError:

175

print("Signature verification failed")

176

177

# Determine hash method without full verification

178

try:

179

hash_method = rsa.find_signature_hash(signature, public_key)

180

print(f"Signature uses {hash_method}")

181

except rsa.VerificationError:

182

print("Cannot determine hash method")

183

```

184

185

### Hash Computation

186

187

Compute cryptographic hashes for messages using supported algorithms.

188

189

```python { .api }

190

def compute_hash(message: Union[bytes, BinaryIO], method_name: str) -> bytes:

191

"""

192

Computes a hash of the given message.

193

194

Parameters:

195

- message: bytes or file-like object - data to hash

196

- method_name: str - hash algorithm ('SHA-1', 'SHA-224', 'SHA-256', 'SHA-384', 'SHA-512', 'MD5')

197

198

Returns:

199

bytes - computed hash value

200

201

Raises:

202

- ValueError: for unsupported hash methods

203

"""

204

```

205

206

**Usage Example:**

207

208

```python

209

import rsa

210

211

# Hash a message

212

message = b'Data to hash'

213

hash_value = rsa.compute_hash(message, 'SHA-256')

214

215

# Hash a file

216

with open('document.txt', 'rb') as f:

217

hash_value = rsa.compute_hash(f, 'SHA-256')

218

```

219

220

221

## Exception Types

222

223

```python { .api }

224

class CryptoError(Exception):

225

"""Base class for all cryptographic errors."""

226

227

class DecryptionError(CryptoError):

228

"""Raised when decryption fails due to wrong key, corrupted data, or padding errors."""

229

230

class VerificationError(CryptoError):

231

"""Raised when signature verification fails due to invalid signature or wrong key."""

232

```

233

234

## Supported Hash Algorithms

235

236

| Algorithm | Security | Recommended |

237

|-----------|----------|-------------|

238

| **SHA-256** | High | ✓ Recommended |

239

| **SHA-384** | High | ✓ Recommended |

240

| **SHA-512** | High | ✓ Recommended |

241

| **SHA-224** | Medium | ✓ Acceptable |

242

| **SHA-1** | Low | ⚠️ Deprecated |

243

| **MD5** | Very Low | ❌ Not recommended |

244

245

## Message Size Limitations

246

247

RSA encryption has strict message size limitations based on key size and padding:

248

249

- **Maximum message size**: `(key_size_in_bytes - 11)` bytes

250

- **2048-bit key**: Maximum 245 bytes per encryption

251

- **1024-bit key**: Maximum 117 bytes per encryption

252

- **4096-bit key**: Maximum 501 bytes per encryption

253

254

For larger messages, use hybrid encryption (encrypt a symmetric key with RSA, then encrypt the message with the symmetric key).

255

256

## Security Best Practices

257

258

### Encryption

259

- Use at least 2048-bit keys (4096-bit for high security)

260

- Never encrypt the same message twice without changing padding

261

- Consider hybrid encryption for large messages

262

263

### Signing

264

- Always use SHA-256 or stronger hash algorithms

265

- Sign the hash of the message, not the message directly for large data

266

- Verify signatures before trusting signed content

267

268

### Key Security

269

- Keep private keys secure and never transmit them unencrypted

270

- Use secure random number generation (automatically handled by the library)

271

- Consider key rotation policies for long-term applications

272

273

## Performance Considerations

274

275

- **Key Generation**: Larger keys take exponentially longer to generate

276

- **Encryption/Decryption**: Performance scales with key size

277

- **Parallel Processing**: Use `poolsize > 1` in `newkeys()` for faster key generation

278

- **Blinding**: Enabled by default to prevent timing attacks (slight performance overhead)