Skip to content

Commit c603761

Browse files
committed
[CRYPTO]: added crypto functionality
Signed-off-by: ashish <[email protected]>
1 parent 58df74f commit c603761

File tree

2 files changed

+184
-61
lines changed

2 files changed

+184
-61
lines changed

src/commands/crypto.ts

Lines changed: 86 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,123 @@
11
import {Command, flags} from '@oclif/command'
22
import * as CryptoJS from 'crypto-js'
3+
import {JsonFormatter} from 'tslint/lib/formatters'
34

45
import Utilities from '../utilities/Utilities'
56
import Logger from '../utilities/Logger'
7+
import Hash from './hash'
68

79
export default class Crypto extends Command {
10+
static ENCRYPTION = 'encryption'
11+
static DECRYPTION = 'decryption'
12+
813
static description = 'Encryption and Decryption functionality'
914
static flags = {
1015
help: flags.help({char: 'h'}),
1116

12-
encryption: flags.string({char: 'e', description: 'encryption type'}),
13-
decryption: flags.string({char: 'd', description: 'decryption type'}),
17+
encryption: flags.string({char: 'e', description: 'encryption type, Supported [AES, DES, 3DES, Rabbit, RC4, RC4Drop]'}),
18+
decryption: flags.string({char: 'd', description: 'decryption type, Supported [AES, DES, 3DES, Rabbit, RC4, RC4Drop]'}),
1419
string: flags.string({char: 's' , description: 'string to be encrypted/decrypted'}),
1520
file: flags.string({char: 'f' , description: 'file to be encrypted/decrypted'}),
1621
key: flags.string({char: 'k' , description: 'key for encryption/decryption'}),
22+
mode: flags.string({char: 'm' , description: 'Block Mode, Supported [CBC, CFB, CTR, OFB, ECB]'})
1723
}
1824

25+
static args = [{name: 'string'}]
26+
27+
//need INPUT_STRING, TYPE_OF_CRYPTO , KEY, MODE
1928
async run() {
2029
const {args, flags} = this.parse(Crypto)
2130

22-
let enc = CryptoJS.DES.encrypt('Message', 'Secret Passphrase').ciphertext
31+
args.string = Hash.getInputString(this,flags,args) //always add input to args
32+
args.type = flags.encryption ? flags.encryption : flags.decryption //type like AES,DES
2333

24-
this.log(enc)
34+
this.checkParameters(flags,args)
35+
flags.encryption ? this.Encrypt(flags, args) : this.Decrypt(flags, args)
2536

26-
// if -s or -f is not passed we will take it from args
27-
let str = ''
37+
}
2838

29-
const {key, decryption, string, file, encryption} = flags
39+
private Encrypt(flags: any, args:any) {
3040

31-
if (string) //if -s given
32-
str = string
33-
else if (file) {
34-
str = Utilities.getStringFromFile(this, file)
35-
} else
36-
str = args.string
41+
let crypto = this.getCryptoType(args.type)
3742

38-
if (!key) {
39-
Logger.error(this,'Key is not passed')
40-
}
43+
Logger.info(this,`Encryption: ${flags.encryption.toUpperCase()}`)
4144

42-
if (encryption) {
43-
if (decryption) // if both given
44-
Logger.error(this,'Both encryption and decryption methods passed')
45-
this.Encrypt(str, encryption, key)
46-
} else if (decryption) {
47-
this.Decrypt(str, decryption, key)
48-
} else {
49-
Logger.error(this,'Neither encryption or decryption methods passed')
50-
}
51-
}
45+
// @ts-ignore // as crypto will never be undefined and reach here
46+
let encrypted: string = crypto.encrypt(args.string, flags.key, {
47+
mode: this.getCryptoMode(this,flags)
48+
}).toString()
5249

53-
private Encrypt(str: string, type: string, key: string | undefined) {
54-
let crypto = this.getCryptoType(type)
55-
56-
if (crypto) {
57-
// @ts-ignore
58-
// let encrypted: string = crypto.encrypt(str, key, {
59-
// mode: CryptoJS.mode.CBC}).ciphertext.toString(CryptoJS.enc.Hex)
60-
let encrypted: string = crypto.encrypt(str, key).ciphertext
61-
this.log(`[${type.toUpperCase()}]: ${encrypted}`)
62-
} else {
63-
Logger.error(this,'invalid hash type')
64-
}
50+
//always add input to args
51+
52+
Logger.success(this,`${encrypted}`)
6553
}
6654

67-
private Decrypt(str: string, type: string, key: string | undefined) {
68-
let crypto = this.getCryptoType(type)
55+
private Decrypt(flags: any, args: any) {
56+
let crypto = this.getCryptoType(args.type)
6957

70-
if (crypto) {
71-
// @ts-ignore
72-
let decrypted: string = crypto.decrypt(str, key)
73-
this.log(`[${type.toUpperCase()}]: ${decrypted}`)
74-
} else {
75-
Logger.error(this,'invalid hash type')
76-
}
58+
Logger.info(this,`Decryption: ${flags.decryption.toUpperCase()}`)
59+
60+
// @ts-ignore // as crypto will never be undefined and reach here
61+
let decrypted: string = crypto.decrypt(args.string, flags.key, {
62+
mode: this.getCryptoMode(this,flags)
63+
}).toString(CryptoJS.enc.Utf8)
64+
65+
Logger.success(this,`${decrypted}`)
7766
}
7867

7968
private getCryptoType(type: string) {
8069
switch (type.toUpperCase()) {
81-
case 'AES':
82-
return CryptoJS.AES
83-
case 'DES':
84-
return CryptoJS.DES
85-
default:
86-
// tslint:disable-next-line:no-return-undefined
87-
return undefined //returning because of check there
70+
case 'AES':
71+
return CryptoJS.AES
72+
case 'DES':
73+
return CryptoJS.DES
74+
case '3DES':
75+
return CryptoJS.TripleDES
76+
case 'RABBIT':
77+
return CryptoJS.Rabbit
78+
case 'RC4':
79+
return CryptoJS.RC4
80+
case 'RC4DROP':
81+
return CryptoJS.RC4Drop
82+
default:
83+
Logger.error(this,'Invalid or Unsupported Encryption/Decryption type')
84+
return undefined // will never reach here
8885
}
8986

9087
}
88+
89+
// to check required parameters passed or not
90+
private checkParameters(flags: any, args: any) {
91+
if (!flags.key)
92+
Logger.error(this,'Key is not passed')
93+
94+
if(args.string == undefined || args.string =="" )
95+
Logger.error(this, 'Input string is empty or undefined')
96+
97+
if (flags.encryption && flags.decryption)
98+
Logger.error(this,'Both encryption and decryption methods passed')
99+
100+
if(!(flags.encryption || flags.decryption))
101+
Logger.error(this,'Neither encryption or decryption methods passed')
102+
}
103+
104+
private getCryptoMode(thisRef: any, flags: any) {
105+
if(!flags.mode) //set default
106+
flags.mode='CBC' // it will not set to flags.mode there in run() but we do not require it
107+
Logger.info(this,'Block Mode: '+flags.mode)
108+
switch (flags.mode.toUpperCase()) {
109+
case 'CBC':
110+
return CryptoJS.mode.CBC
111+
case 'CFB':
112+
return CryptoJS.mode.CFB
113+
case 'OFB':
114+
return CryptoJS.mode.OFB
115+
case 'ECB':
116+
return CryptoJS.mode.ECB
117+
default:
118+
Logger.error(this,'Invalid or Unsupported Block Mode')
119+
return undefined // will never reach here
120+
}
121+
}
122+
91123
}

test/commands/crypto.test.ts

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,110 @@
11
import {expect, test} from '@oclif/test'
22

33
describe('crypto', () => {
4+
// // TODO: its not possible to predict the encription for a message so we can't write this,however decription is predictible
5+
// test
6+
// .stdout()
7+
// .command(['crypto', '-e', 'aes', '-s', 'Message', '-k', 'Secret Passphrase'])
8+
// .it('runs hello', ctx => {
9+
// expect(ctx.stdout).to.contain('73e54154a15d1beeb509d9e12f1e462a0')
10+
// })
11+
//
12+
13+
test
14+
.stdout()
15+
.command(['crypto', '-d', 'aes', 'U2FsdGVkX1/OLQ6Lp+V3O1d5SaxEf9pAf8CV7ErBC9o=', '-k', 'Secret Passphrase'])
16+
.it('AES Decryption string passed as string argument', ctx => {
17+
expect(ctx.stdout).to.contain('Message')
18+
})
19+
20+
test
21+
.stdout()
22+
.command(['crypto', '-d', 'aes', '-s','U2FsdGVkX1/OLQ6Lp+V3O1d5SaxEf9pAf8CV7ErBC9o=', '-k', 'Secret Passphrase'])
23+
.it('AES Decryption string passed as flag', ctx => {
24+
expect(ctx.stdout).to.contain('Message')
25+
})
26+
27+
test
28+
.stdout()
29+
.command(['crypto', '-d', 'des', '-s','U2FsdGVkX180d+J1kUcxGL9bbBAErXAw', '-k', 'Secret Passphrase'])
30+
.it('DES Decryption', ctx => {
31+
expect(ctx.stdout).to.contain('Message')
32+
})
33+
34+
test
35+
.stdout()
36+
.command(['crypto', '-d', 'des', '-s','U2FsdGVkX186YglxZ7yF7aqTjFQA3Yzs', '-k', 'Secret Passphrase','-m','ECB'])
37+
.it('DES Decryption with Mode ECB', ctx => {
38+
expect(ctx.stdout).to.contain('Message')
39+
})
40+
41+
test
42+
.stdout()
43+
.command(['crypto', '-d', '3des', '-s','U2FsdGVkX1+2jkjCxuWwL8uMgdu6SXJc', '-k', 'Secret Passphrase'])
44+
.it('3DES Decryption', ctx => {
45+
expect(ctx.stdout).to.contain('Message')
46+
})
47+
48+
test
49+
.stdout()
50+
.command(['crypto', '-d', 'RABBIT', '-s','U2FsdGVkX185oOsUqvpF+7x0zPUxNJw=', '-k', 'Secret Passphrase'])
51+
.it('RABBIT Decryption', ctx => {
52+
expect(ctx.stdout).to.contain('Message')
53+
})
54+
55+
test
56+
.stdout()
57+
.command(['crypto', '-d', 'RC4', '-s','U2FsdGVkX1+/oErpaqQQk1Fj2eXwL1o=', '-k', 'Secret Passphrase'])
58+
.it('RC4 Decryption', ctx => {
59+
expect(ctx.stdout).to.contain('Message')
60+
})
61+
462
test
563
.stdout()
6-
.command(['crypto', '-e', 'aes', '-s', 'Message', '-k', 'Secret Passphrase'])
7-
.it('runs hello', ctx => {
8-
expect(ctx.stdout).to.contain('73e54154a15d1beeb509d9e12f1e462a0')
64+
.command(['crypto', '-d', 'RC4DROP', '-s','U2FsdGVkX18+D1WNQ64XzaCwkUM6moE=', '-k', 'Secret Passphrase'])
65+
.it('RC4Drop Decryption', ctx => {
66+
expect(ctx.stdout).to.contain('Message')
967
})
1068

11-
//values passed as string argument
1269
test
1370
.stdout()
14-
.command(['crypto', '-e', 'aes', 'Message', '-k', 'Secret Passphrase'])
15-
.it('runs hello', ctx => {
16-
expect(ctx.stdout).to.contain('73e54154a15d1beeb509d9e12f1e462a0')
71+
.command(['crypto', '-e', 'aes', '-k', 'Secret Passphrase', 'Message', '-m', 'INVALID'])
72+
.exit(0)
73+
.it('Invalid or Unsupported Block Mode', ctx => {
74+
expect(ctx.stdout).to.contain('Invalid or Unsupported Block Mode')
1775
})
1876

77+
test
78+
.stdout()
79+
.command(['crypto', '-e', 'aes', '-k', 'Secret Passphrase'])
80+
.exit(0)
81+
.it('Input string is empty or undefined', ctx => {
82+
expect(ctx.stdout).to.contain('Input string is empty or undefined')
83+
})
84+
85+
test
86+
.stdout()
87+
.command(['crypto', '-e', 'aes', '-s', 'Message'])
88+
.exit(0)
89+
.it('if key not passed', ctx => {
90+
expect(ctx.stdout).to.contain('Key is not passed')
91+
})
92+
93+
test
94+
.stdout()
95+
.command(['crypto', '-e', 'aes','-d', 'aes', '-s', 'Message', '-k', 'Secret Passphrase'])
96+
.exit(0)
97+
.it('Both encryption and decryption methods passed', ctx => {
98+
expect(ctx.stdout).to.contain('Both encryption and decryption methods passed')
99+
})
100+
101+
test
102+
.stdout()
103+
.command(['crypto', '-s', 'Message', '-k', 'Secret Passphrase'])
104+
.exit(0)
105+
.it('Neither encryption nor decryption method passed', ctx => {
106+
expect(ctx.stdout).to.contain('Neither encryption or decryption methods passed')
107+
})
108+
109+
19110
})

0 commit comments

Comments
 (0)