cipher-shield 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * cipher-shield v2.1 - Production Security Middleware
3
+ *
4
+ * A comprehensive, multi-layered security middleware for Node.js/Express applications.
5
+ * Provides AES encryption, ghost route protection, shadow banning, AI-powered
6
+ * threat detection, adaptive DEFCON escalation, and automated SSL certificate management.
7
+ *
8
+ * @module cipher-shield
9
+ * @version 1.0.0
10
+ * @author cipher-shield Team
11
+ * @license MIT
12
+ *
13
+ * @example
14
+ * ```javascript
15
+ * const express = require('express');
16
+ * const cipherShield = require('cipher-shield');
17
+ *
18
+ * const app = express();
19
+ * app.use(express.json());
20
+ *
21
+ * // Apply security middleware
22
+ * app.use(cipherShield({
23
+ * encryption: {
24
+ * enabled: true,
25
+ * algorithm: 'aes-256-gcm',
26
+ * secretKey: 'your-32-character-secret-key-here!!!'
27
+ * },
28
+ * ghostRoutes: ['/admin', '/.env', '/.git'],
29
+ * shadowBan: { enabled: true, delayTime: 5000 },
30
+ * aiGate: {
31
+ * enabled: true,
32
+ * provider: 'gemini',
33
+ * gemini: { apiKey: process.env.GEMINI_API_KEY }
34
+ * }
35
+ * }));
36
+ *
37
+ * // Enable SSL (new feature)
38
+ * const shield = new cipherShield.CipherShield({
39
+ * // config
40
+ * });
41
+ * await shield.enableSSL({
42
+ * email: 'admin@example.com',
43
+ * domains: ['example.com'],
44
+ * staging: true
45
+ * });
46
+ *
47
+ * // Your routes are now protected
48
+ * app.get('/api/data', (req, res) => res.json({ secure: true }));
49
+ * ```
50
+ *
51
+ * @see {@link https://github.com/your-repo/cipher-shield|GitHub Repository}
52
+ * @see {@link https://cipher-shield.dev|Documentation}
53
+ */
54
+
55
+ // Import the CipherShield class
56
+ const CipherShield = require('./src/shield');
57
+ const SmartLogger = require('./src/smartLogger');
58
+ const MagicAuth = require('./src/magicAuth');
59
+ const { encrypt, decrypt, generateKey } = require('./src/core/aesEngine');
60
+
61
+ // Backward compatibility: when called as a function, create instance and return middleware
62
+ function cipherShieldFactory(config) {
63
+ const instance = new CipherShield(config);
64
+ return instance.middleware();
65
+ }
66
+
67
+ // Export both the factory function (for backward compatibility) and the class
68
+ cipherShieldFactory.CipherShield = CipherShield;
69
+ cipherShieldFactory.SmartLogger = SmartLogger;
70
+ cipherShieldFactory.MagicAuth = MagicAuth;
71
+ cipherShieldFactory.encrypt = encrypt;
72
+ cipherShieldFactory.decrypt = decrypt;
73
+ cipherShieldFactory.generateKey = generateKey;
74
+
75
+ module.exports = cipherShieldFactory;
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "cipher-shield",
3
+ "version": "1.0.0",
4
+ "description": "Advanced active defense middleware for Node.js/Express with AES encryption, honeypot detection, AI threat analysis, and adaptive security. Features 9 AES algorithms, ghost routes, shadow ban, and DEFCON system.",
5
+ "main": "index.js",
6
+ "files": [
7
+ "src",
8
+ "index.js"
9
+ ],
10
+ "keywords": [
11
+ "security",
12
+ "middleware",
13
+ "express",
14
+ "honeypot",
15
+ "active-defense",
16
+ "aes",
17
+ "aes-gcm",
18
+ "aes-cbc",
19
+ "aes-ctr",
20
+ "ai-security",
21
+ "openai",
22
+ "gemini"
23
+ ],
24
+ "author": "Omindu Dissanayaka",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "@google/generative-ai": "^0.24.1",
28
+ "acme-client": "^5.4.0",
29
+ "express": "^5.2.1",
30
+ "express-rate-limit": "^8.2.1",
31
+ "helmet": "^8.1.0",
32
+ "jsonwebtoken": "^9.0.3",
33
+ "node-forge": "^1.3.3",
34
+ "on-headers": "^1.1.0",
35
+ "openai": "^6.16.0"
36
+ },
37
+ "optionalDependencies": {
38
+ "dotenv": "^17.2.3"
39
+ },
40
+ "engines": {
41
+ "node": ">=14.0.0"
42
+ },
43
+ "directories": {
44
+ "example": "examples"
45
+ },
46
+ "scripts": {
47
+ "test": "node testing/test-suite.js"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/OminduDissanayaka/cipher-shield.git"
52
+ },
53
+ "bugs": {
54
+ "url": "https://github.com/OminduDissanayaka/cipher-shield/issues"
55
+ },
56
+ "homepage": "https://github.com/OminduDissanayaka/cipher-shield#readme"
57
+ }
@@ -0,0 +1,369 @@
1
+ /**
2
+ * Advanced AES Encryption/Decryption Engine v2.1
3
+ *
4
+ * High-performance AES encryption engine supporting multiple modes:
5
+ * - AES-256-GCM (recommended for authenticated encryption)
6
+ * - AES-256-CBC, AES-192-GCM/CBC/CTR, AES-128-GCM/CBC/CTR
7
+ *
8
+ * Features:
9
+ * - Authenticated encryption with GCM mode
10
+ * - Secure random IV generation
11
+ * - Comprehensive error handling
12
+ * - Performance optimized for high-throughput scenarios
13
+ *
14
+ * @module aesEngine
15
+ * @version 1.0.0
16
+ * @author Omindu Dissanayaka
17
+ * @license MIT
18
+ */
19
+
20
+ const crypto = require('crypto');
21
+
22
+ /**
23
+ * AES algorithm configurations with security parameters
24
+ * Each algorithm defines key length, IV length, and authentication properties
25
+ *
26
+ * @constant {Object.<string, Object>}
27
+ * @readonly
28
+ */
29
+ const ALGORITHMS = Object.freeze({
30
+ 'aes-256-cbc': Object.freeze({
31
+ name: 'aes-256-cbc',
32
+ keyLength: 32,
33
+ ivLength: 16,
34
+ authTag: false
35
+ }),
36
+ 'aes-256-gcm': Object.freeze({
37
+ name: 'aes-256-gcm',
38
+ keyLength: 32,
39
+ ivLength: 12,
40
+ authTag: true,
41
+ authTagLength: 16
42
+ }),
43
+ 'aes-256-ctr': Object.freeze({
44
+ name: 'aes-256-ctr',
45
+ keyLength: 32,
46
+ ivLength: 16,
47
+ authTag: false
48
+ }),
49
+ 'aes-192-cbc': Object.freeze({
50
+ name: 'aes-192-cbc',
51
+ keyLength: 24,
52
+ ivLength: 16,
53
+ authTag: false
54
+ }),
55
+ 'aes-192-gcm': Object.freeze({
56
+ name: 'aes-192-gcm',
57
+ keyLength: 24,
58
+ ivLength: 12,
59
+ authTag: true,
60
+ authTagLength: 16
61
+ }),
62
+ 'aes-192-ctr': Object.freeze({
63
+ name: 'aes-192-ctr',
64
+ keyLength: 24,
65
+ ivLength: 16,
66
+ authTag: false
67
+ }),
68
+ 'aes-128-cbc': Object.freeze({
69
+ name: 'aes-128-cbc',
70
+ keyLength: 16,
71
+ ivLength: 16,
72
+ authTag: false
73
+ }),
74
+ 'aes-128-gcm': Object.freeze({
75
+ name: 'aes-128-gcm',
76
+ keyLength: 16,
77
+ ivLength: 12,
78
+ authTag: true,
79
+ authTagLength: 16
80
+ }),
81
+ 'aes-128-ctr': Object.freeze({
82
+ name: 'aes-128-ctr',
83
+ keyLength: 16,
84
+ ivLength: 16,
85
+ authTag: false
86
+ })
87
+ });
88
+
89
+ /**
90
+ * Cached algorithm configurations for performance
91
+ * Avoids repeated object lookups during encryption/decryption
92
+ *
93
+ * @private
94
+ * @type {Map<string, Object>}
95
+ */
96
+ const algorithmCache = new Map();
97
+
98
+ /**
99
+ * Retrieves and caches algorithm configuration for performance
100
+ *
101
+ * @private
102
+ * @param {string} algorithm - AES algorithm name
103
+ * @returns {Object} Algorithm configuration object
104
+ * @throws {Error} If algorithm is not supported
105
+ */
106
+ function getAlgorithmConfig(algorithm) {
107
+ if (algorithmCache.has(algorithm)) {
108
+ return algorithmCache.get(algorithm);
109
+ }
110
+
111
+ const config = ALGORITHMS[algorithm];
112
+ if (!config) {
113
+ const supported = Object.keys(ALGORITHMS).join(', ');
114
+ throw new Error(`Unsupported AES algorithm: ${algorithm}. Supported: ${supported}`);
115
+ }
116
+
117
+ algorithmCache.set(algorithm, config);
118
+ return config;
119
+ }
120
+
121
+ /**
122
+ * Validates secret key length and format for security
123
+ *
124
+ * @private
125
+ * @param {string} secretKey - The encryption/decryption key
126
+ * @param {number} requiredLength - Required key length in bytes
127
+ * @param {string} algorithm - Algorithm name for error messages
128
+ * @throws {Error} If key is invalid
129
+ */
130
+ function validateKeyLength(secretKey, requiredLength, algorithm) {
131
+ if (!secretKey) {
132
+ throw new Error(`Secret key is required for ${algorithm}`);
133
+ }
134
+
135
+ if (typeof secretKey !== 'string') {
136
+ throw new Error(`Secret key must be a string for ${algorithm}`);
137
+ }
138
+
139
+ const expectedLength = requiredLength * 2;
140
+ if (secretKey.length !== expectedLength) {
141
+ throw new Error(`${algorithm} requires a ${expectedLength}-character hex-encoded secret key (got ${secretKey.length})`);
142
+ }
143
+
144
+ if (!/^[0-9a-fA-F]+$/.test(secretKey)) {
145
+ throw new Error(`Secret key must be valid hexadecimal for ${algorithm}`);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Validates encrypted data format before decryption
151
+ *
152
+ * @private
153
+ * @param {string} encryptedData - The encrypted data string
154
+ * @param {boolean} expectsAuthTag - Whether auth tag is expected
155
+ * @param {string} algorithm - Algorithm name for error messages
156
+ * @returns {Object} Parsed encryption components
157
+ * @throws {Error} If format is invalid
158
+ */
159
+ function parseEncryptedData(encryptedData, expectsAuthTag, algorithm) {
160
+ if (!encryptedData || typeof encryptedData !== 'string') {
161
+ throw new Error('Encrypted data must be a non-empty string');
162
+ }
163
+
164
+ const parts = encryptedData.split(':');
165
+ const expectedParts = expectsAuthTag ? 4 : 3;
166
+
167
+ if (parts.length !== expectedParts) {
168
+ const format = expectsAuthTag ? 'algorithm:iv:authTag:encryptedData' : 'algorithm:iv:encryptedData';
169
+ throw new Error(`Invalid ${algorithm} encrypted data format. Expected: ${format}`);
170
+ }
171
+
172
+ const parsedAlgorithm = parts[0];
173
+ if (parsedAlgorithm !== algorithm) {
174
+ throw new Error(`Algorithm mismatch: expected ${algorithm}, got ${parsedAlgorithm}`);
175
+ }
176
+
177
+ return {
178
+ algorithm: parsedAlgorithm,
179
+ ivHex: parts[1],
180
+ authTagHex: expectsAuthTag ? parts[2] : null,
181
+ encryptedHex: expectsAuthTag ? parts[3] : parts[2]
182
+ };
183
+ }
184
+
185
+ /**
186
+ * Encrypts plaintext using specified AES algorithm with authenticated encryption
187
+ *
188
+ * Supports multiple AES modes with automatic IV generation and authentication tags
189
+ * for GCM mode. Uses cryptographically secure random IVs.
190
+ *
191
+ * @param {string} plaintext - The text to encrypt
192
+ * @param {string} secretKey - The encryption key (length must match algorithm requirements)
193
+ * @param {string} [algorithm='aes-256-gcm'] - AES algorithm to use
194
+ * @returns {string} Encrypted data in format: algorithm:iv[:authTag]:encryptedData
195
+ *
196
+ * @throws {Error} If parameters are invalid or encryption fails
197
+ *
198
+ * @example
199
+ * ```javascript
200
+ * const encrypted = aesEngine.encrypt('Hello World', 'my-32-char-secret-key!!!', 'aes-256-gcm');
201
+ * // Returns: aes-256-gcm:a1b2c3...:d4e5f6...:encrypted-data
202
+ * ```
203
+ */
204
+ function encrypt(plaintext, secretKey, algorithm = 'aes-256-gcm') {
205
+ if (!plaintext || typeof plaintext !== 'string') {
206
+ throw new Error('Plaintext must be a non-empty string');
207
+ }
208
+
209
+ const config = getAlgorithmConfig(algorithm);
210
+ validateKeyLength(secretKey, config.keyLength, algorithm);
211
+
212
+ try {
213
+ const iv = crypto.randomBytes(config.ivLength);
214
+ const cipher = crypto.createCipheriv(config.name, Buffer.from(secretKey, 'hex'), iv);
215
+
216
+ let encrypted = cipher.update(plaintext, 'utf8', 'hex');
217
+ encrypted += cipher.final('hex');
218
+
219
+ if (config.authTag) {
220
+ const authTag = cipher.getAuthTag();
221
+ return `${algorithm}:${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
222
+ }
223
+
224
+ return `${algorithm}:${iv.toString('hex')}:${encrypted}`;
225
+
226
+ } catch (error) {
227
+ throw new Error(`AES encryption failed for ${algorithm}: ${error.message}`);
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Decrypts AES encrypted data with integrity verification
233
+ *
234
+ * Automatically detects encryption format and validates integrity for authenticated modes.
235
+ * Provides comprehensive error handling for corrupted or tampered data.
236
+ *
237
+ * @param {string} encryptedData - The encrypted data string
238
+ * @param {string} secretKey - The decryption key
239
+ * @param {string} [algorithm] - Optional algorithm override (auto-detected from data)
240
+ * @returns {string} The decrypted plaintext
241
+ *
242
+ * @throws {Error} If decryption fails, data is corrupted, or authentication fails
243
+ *
244
+ * @example
245
+ * ```javascript
246
+ * const decrypted = aesEngine.decrypt(encryptedString, 'my-32-char-secret-key!!!');
247
+ * console.log(decrypted); // 'Hello World'
248
+ * ```
249
+ */
250
+ function decrypt(encryptedData, secretKey, algorithm) {
251
+ try {
252
+ const parts = encryptedData.split(':');
253
+
254
+ const detectedAlgorithm = algorithm || parts[0];
255
+ const config = getAlgorithmConfig(detectedAlgorithm);
256
+
257
+ const parsed = parseEncryptedData(encryptedData, config.authTag, detectedAlgorithm);
258
+ validateKeyLength(secretKey, config.keyLength, detectedAlgorithm);
259
+
260
+ const iv = Buffer.from(parsed.ivHex, 'hex');
261
+ const encrypted = parsed.encryptedHex;
262
+
263
+ if (iv.length !== config.ivLength) {
264
+ throw new Error(`Invalid IV length for ${detectedAlgorithm}: expected ${config.ivLength}, got ${iv.length}`);
265
+ }
266
+
267
+ const decipher = crypto.createDecipheriv(config.name, Buffer.from(secretKey, 'hex'), iv);
268
+
269
+ if (config.authTag) {
270
+ const authTag = Buffer.from(parsed.authTagHex, 'hex');
271
+ if (authTag.length !== config.authTagLength) {
272
+ throw new Error(`Invalid auth tag length for ${detectedAlgorithm}: expected ${config.authTagLength}, got ${authTag.length}`);
273
+ }
274
+ decipher.setAuthTag(authTag);
275
+ }
276
+
277
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
278
+ decrypted += decipher.final('utf8');
279
+
280
+ return decrypted;
281
+
282
+ } catch (error) {
283
+ if (error.message.includes('Unsupported state') || error.message.includes('Tag mismatch')) {
284
+ throw new Error(`Authentication failed: data may be corrupted or tampered with`);
285
+ }
286
+ if (error.message.includes('Invalid key length')) {
287
+ throw new Error(`Key length mismatch: ensure correct key for the algorithm`);
288
+ }
289
+ throw new Error(`AES decryption failed: ${error.message}`);
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Generates a cryptographically secure random secret key for the specified algorithm
295
+ *
296
+ * Uses Node.js crypto.randomBytes() for maximum security. The generated key
297
+ * is suitable for immediate use with the corresponding AES algorithm.
298
+ *
299
+ * @param {string} [algorithm='aes-256-gcm'] - AES algorithm for key generation
300
+ * @returns {string} Random secret key of correct length for the algorithm
301
+ *
302
+ * @example
303
+ * ```javascript
304
+ * const key = aesEngine.generateKey('aes-256-gcm'); // 64-character hex key
305
+ * const encrypted = aesEngine.encrypt('data', key, 'aes-256-gcm');
306
+ * ```
307
+ */
308
+ function generateKey(algorithm = 'aes-256-gcm') {
309
+ const config = getAlgorithmConfig(algorithm);
310
+
311
+ try {
312
+ const keyBytes = crypto.randomBytes(config.keyLength);
313
+ return keyBytes.toString('hex');
314
+ } catch (error) {
315
+ throw new Error(`Key generation failed for ${algorithm}: ${error.message}`);
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Returns list of all supported AES algorithms
321
+ *
322
+ * @returns {string[]} Array of supported algorithm names
323
+ *
324
+ * @example
325
+ * ```javascript
326
+ * console.log(aesEngine.getSupportedAlgorithms());
327
+ * // ['aes-256-cbc', 'aes-256-gcm', 'aes-256-ctr', ...]
328
+ * ```
329
+ */
330
+ function getSupportedAlgorithms() {
331
+ return Object.keys(ALGORITHMS);
332
+ }
333
+
334
+ /**
335
+ * Retrieves detailed information about a specific AES algorithm
336
+ *
337
+ * @param {string} algorithm - AES algorithm name
338
+ * @returns {Object} Algorithm information object
339
+ * @property {string} algorithm - Algorithm name
340
+ * @property {number} keyLength - Required key length in characters
341
+ * @property {number} ivLength - IV length in bytes
342
+ * @property {boolean} authenticationTag - Whether algorithm uses auth tags
343
+ * @property {number|null} authTagLength - Auth tag length in bytes (GCM only)
344
+ *
345
+ * @example
346
+ * ```javascript
347
+ * const info = aesEngine.getAlgorithmInfo('aes-256-gcm');
348
+ * console.log(info.keyLength); // 32
349
+ * ```
350
+ */
351
+ function getAlgorithmInfo(algorithm) {
352
+ const config = getAlgorithmConfig(algorithm);
353
+ return {
354
+ algorithm: config.name,
355
+ keyLength: config.keyLength * 2,
356
+ ivLength: config.ivLength,
357
+ authenticationTag: config.authTag,
358
+ authTagLength: config.authTag ? config.authTagLength : null
359
+ };
360
+ }
361
+
362
+ module.exports = {
363
+ encrypt,
364
+ decrypt,
365
+ generateKey,
366
+ getSupportedAlgorithms,
367
+ getAlgorithmInfo,
368
+ ALGORITHMS
369
+ };