ig-crypto-utils 0.0.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec754385ef30a08d89b3c0b866245b404a50868a
4
+ data.tar.gz: 369c33e30159d8e254ae73dbe447d359c6eb7f2a
5
+ SHA512:
6
+ metadata.gz: 727072d7053adf71cce4fbd9bab32a2ac3b99145fe5f31b203a45aa3d817adbd700b3618f5896a09e9fb8cd201e622043667ff377fa5975de62c53cac5772578
7
+ data.tar.gz: dac2ad1dd4a0159bc10410d945a570220db8e145b528b1e2bb3793f260b6b32043a59c8bc4e72ec587b8b41cdd25580915e12a0eba8e3eb319e63539380ce51d
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'ig-crypto-utils'
3
+ s.version = '0.0.2'
4
+ s.date = '2015-04-17'
5
+ s.summary = 'AES and EDCSA utils based on OpenSSL'
6
+ s.description = 'Asymmetric/symmetric encryption utility'
7
+ s.authors = ['Infinity-G']
8
+ s.email = 'developer@infinity-g.com'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.require_paths = ["lib"]
11
+ s.homepage = ''
12
+ s.license = 'MIT'
13
+ end
14
+
15
+ # run 'gem build ig-crypto-utils' to create gem
16
+ # run
@@ -0,0 +1,142 @@
1
+ require 'securerandom'
2
+ require 'digest'
3
+ require 'base64'
4
+ require 'openssl'
5
+
6
+ # NOTE: All inputs of methods in this module require Base64 encoding!
7
+ # Outputs are all Base64 encoded
8
+
9
+ module CryptoUtils
10
+
11
+ # General use static functions
12
+
13
+ def self.encode_base64(value)
14
+ unless value =~ /^([A-Za-z0-9+]{4})*([A-Za-z0-9+]{4}|[A-Za-z0-9+]{3}=|[A-Za-z0-9+]{2}==)$/i
15
+ puts "#{value} is NOT base64 encoded, ENCODING..."
16
+ return Base64.encode64 value
17
+ end
18
+
19
+ value
20
+ end
21
+
22
+ def self.decode_base64(value)
23
+ if value =~ /^([A-Za-z0-9+]{4})*([A-Za-z0-9+]{4}|[A-Za-z0-9+]{3}=|[A-Za-z0-9+]{2}==)$/i
24
+ puts "#{value} is base64 encoded, ...DECODING"
25
+ return Base64.decode64 value
26
+ end
27
+
28
+ value
29
+ end
30
+
31
+ def self.create_digest(value)
32
+ Digest::SHA2.base64digest value
33
+ end
34
+
35
+ #############################
36
+ # SYMMETRIC ENCRYPTION UTIL
37
+ #############################
38
+
39
+ class AesUtil
40
+ # https://gist.github.com/byu/99651
41
+ # http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/Cipher.html
42
+
43
+ def encrypt(encoded_plain_text, encoded_key)
44
+
45
+ cipher = OpenSSL::Cipher::AES.new(256, :CBC) # CBC = cipher block chaining
46
+ cipher.encrypt
47
+
48
+ # generate a random iv
49
+ iv = cipher.random_iv
50
+
51
+ cipher.key = encoded_key
52
+ cipher.iv = iv
53
+
54
+ result = cipher.update(encoded_plain_text) + cipher.final
55
+
56
+ encoded_result = Base64.encode64 result
57
+ encoded_iv = Base64.encode64 iv
58
+
59
+ {:cipher_text => encoded_result, :iv => encoded_iv}
60
+ end
61
+
62
+ def decrypt(encoded_cipher_text, encoded_key, encoded_iv)
63
+
64
+ decoded_cipher_text = Base64.decode64 encoded_cipher_text
65
+ decoded_iv = Base64.decode64 encoded_iv
66
+
67
+ cipher = OpenSSL::Cipher::AES.new(256, :CBC)
68
+ cipher.decrypt
69
+
70
+ cipher.key = encoded_key
71
+ cipher.iv = decoded_iv
72
+
73
+ cipher.update(decoded_cipher_text) + cipher.final
74
+ end
75
+
76
+ end
77
+
78
+ ##########################
79
+ # ASYMMETRIC SIGNING UTIL
80
+ ##########################
81
+
82
+ class EcdsaUtil
83
+
84
+ # for a 256-bit ECDSA curve, the uncompressed pubkey is 512 bits (256 bits of x, 256 bits of y, no sign bit).
85
+ # The compressed pubkey is 257 bits (256 bits of x, one bit of the sign of y).
86
+ def create_key_pair
87
+ group_name = 'secp256k1'
88
+
89
+ # set compression to true for key generation on the group
90
+ group = OpenSSL::PKey::EC::Group.new(group_name)
91
+ group.point_conversion_form = :compressed
92
+
93
+ # instantiate the curve and generate the keys
94
+ curve = OpenSSL::PKey::EC.new(group)
95
+ curve.generate_key
96
+
97
+ public_key = curve.public_key
98
+ private_key = curve.private_key
99
+
100
+ # get binary representation of keys
101
+ pk_bn_bin = public_key.to_bn.to_s(2)
102
+ sk_bn_bin = private_key.to_s(2)
103
+
104
+ #base64 encode keys
105
+ encoded_pk = Base64.encode64(pk_bn_bin)
106
+ encoded_sk = Base64.encode64(sk_bn_bin)
107
+
108
+ {:pk => encoded_pk, :sk => encoded_sk}
109
+
110
+ end
111
+
112
+ def sign(encoded_data, encoded_private_key)
113
+ group_name = 'secp256k1'
114
+
115
+ decoded_data = Base64.decode64 encoded_data
116
+ decoded_private_key = Base64.decode64 encoded_private_key
117
+
118
+ curve = OpenSSL::PKey::EC.new(group_name)
119
+ curve.private_key = OpenSSL::BN.new(decoded_private_key, 2)
120
+
121
+ result = curve.dsa_sign_asn1 decoded_data
122
+
123
+ Base64.encode64 result
124
+ end
125
+
126
+ def validate_signature(encoded_digest, encoded_signature, encoded_public_key)
127
+ group_name = 'secp256k1'
128
+
129
+ decoded_signature = Base64.decode64 encoded_signature
130
+ decoded_digest = Base64.decode64 encoded_digest
131
+ decoded_public_key = Base64.decode64 encoded_public_key
132
+
133
+ curve = OpenSSL::PKey::EC.new(group_name)
134
+ key_bn = OpenSSL::BN.new(decoded_public_key, 2)
135
+ group = OpenSSL::PKey::EC::Group.new(group_name)
136
+ curve.public_key = OpenSSL::PKey::EC::Point.new(group, key_bn)
137
+
138
+ curve.dsa_verify_asn1(decoded_digest, decoded_signature)
139
+ end
140
+ end
141
+
142
+ end
@@ -0,0 +1,27 @@
1
+ require 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'base64'
4
+
5
+ require_relative '../../ig-crypto-utils/lib/ig-crypto-utils'
6
+
7
+ class AesTests < MiniTest::Test
8
+
9
+ def test_encrypt
10
+ # NOTE: AesUtil methods expect all inputs to be Base64 encoded
11
+
12
+ util = CryptoUtils::AesUtil.new
13
+
14
+ plain_text = '{"blah":"Super secret text"}'
15
+ encoded_plain_text = Base64.encode64 plain_text
16
+
17
+ aes_256_key = 'ky4xgi0+KvLYmVp1J5akqkJkv8z5rJsHTo9FcBc0hgo=' # already base64 encoded
18
+
19
+ # encrypt
20
+ encrypted_result = util.encrypt encoded_plain_text, aes_256_key
21
+
22
+ # decrypt
23
+ decrypted_result = util.decrypt encrypted_result[:cipher_text], aes_256_key, encrypted_result[:iv]
24
+
25
+ assert decrypted_result == encoded_plain_text
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ require 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'base64'
4
+
5
+ require_relative '../../ig-crypto-utils/lib/ig-crypto-utils'
6
+
7
+ class EcdsaTests < MiniTest::Test
8
+
9
+ def test_create_key_pair
10
+ result = CryptoUtils::EcdsaUtil.new.create_key_pair
11
+
12
+ assert result[:pk]!= nil
13
+ assert result[:sk]!= nil
14
+ end
15
+
16
+ def test_sign
17
+ text = 'Text to sign'
18
+ text_digest = CryptoUtils.create_digest text
19
+ encoded_text_digest = Base64.encode64 text_digest
20
+
21
+ encoded_secret_key = 'gCrHtl8VVWs6EuJLy7vPqVdBZWzRAR9ZCjIRRpoWvME=' # already base64 encoded
22
+ encoded_public_key = 'Ag7PunGy2BmnAi+PGE4/Dm9nCg1URv8wLZwSOggyfmAn' # already base64 encoded
23
+
24
+ util = CryptoUtils::EcdsaUtil.new
25
+
26
+ # sign
27
+ encoded_result = util.sign encoded_text_digest, encoded_secret_key
28
+
29
+ # validate
30
+ validation_result = util.validate_signature encoded_text_digest, encoded_result, encoded_public_key
31
+
32
+ puts validation_result
33
+ assert validation_result
34
+
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ig-crypto-utils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Infinity-G
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Asymmetric/symmetric encryption utility
14
+ email: developer@infinity-g.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ig-crypto-utils.gemspec
20
+ - lib/ig-crypto-utils.rb
21
+ - tests/aes_tests.rb
22
+ - tests/ecdsa_tests.rb
23
+ homepage: ''
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.4.2
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: AES and EDCSA utils based on OpenSSL
47
+ test_files: []