keystores 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/JAVA_KEY_STORE_README.md +58 -0
- data/README.md +6 -3
- data/keystores.gemspec +3 -2
- data/lib/keystores.rb +4 -3
- data/lib/keystores/jks/encrypted_private_key_info.rb +7 -0
- data/lib/keystores/jks/key_protector.rb +2 -1
- data/lib/keystores/jks/pkcs8_key.rb +1 -2
- data/lib/keystores/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2cf8155852be0f372803bf45bc5eac1a4ea467e
|
4
|
+
data.tar.gz: ff0423f51a7a95deb0ae2e2fbff565a9e4c95366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e46edf529317b03d78a96065d079dcd528a645ead5487e33363209ee6661fd3760cdfa4f1c4138e58c86c2e6e81bfb2e78649e463c994af1b9ba14508dd57b3d
|
7
|
+
data.tar.gz: 4650005587aff20f7c16e0a8fa4627047dcff2b45d91b13b96ccc3310e65c3456472cfcc051a78e262e277e0bd3b422f979c05b4b60a98ec3f327128a4c72329
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Java Key Store
|
2
|
+
==============
|
3
|
+
|
4
|
+
There are quite a few pieces that go into implementing a Java key store that we had to roll ourselves
|
5
|
+
|
6
|
+
## Encrypted private key info
|
7
|
+
|
8
|
+
[Keystores::Jks::EncryptedPrivateKeyInfo](lib/keystores/jks/encrypted_private_key_info.rb)
|
9
|
+
|
10
|
+
PKCS#8 defines the following syntax for an encrypted private key:
|
11
|
+
|
12
|
+
```
|
13
|
+
EncryptedPrivateKeyInfo ::= SEQUENCE {
|
14
|
+
encryptionAlgorithm AlgorithmIdentifier,
|
15
|
+
encryptedData OCTET STRING }
|
16
|
+
```
|
17
|
+
|
18
|
+
Java's implementation actually encodes the following:
|
19
|
+
|
20
|
+
```
|
21
|
+
EncryptedPrivateKeyInfo ::= SEQUENCE {
|
22
|
+
SEQUENCE {
|
23
|
+
null,
|
24
|
+
encryptionAlgorithm AlgorithmIdentifier},
|
25
|
+
encryptedData OCTET STRING }
|
26
|
+
```
|
27
|
+
|
28
|
+
For some reason, they wrap the PKCS8 sequence in another sequence, and throw a null in there for good measure.
|
29
|
+
|
30
|
+
## Key protector
|
31
|
+
|
32
|
+
[Keystores::Jks::KeyProtector](lib/keystores/jks/key_protector.rb)
|
33
|
+
|
34
|
+
This class is pretty much a direct port of `sun.security.provider.KeyProtector`.
|
35
|
+
It implements a proprietary PBE of sorts.
|
36
|
+
|
37
|
+
TODO, I would like to implement this as a proper `OpenSSL::Cipher` object.
|
38
|
+
|
39
|
+
## PKCS8 Key
|
40
|
+
|
41
|
+
This file cracks open the `OpenSSL::PKey` classes and enables them to both parse and encode keys
|
42
|
+
in PKCS#8 format. This is implemented for `EC`, `RSA`, and `DSA` keys.
|
43
|
+
|
44
|
+
### Parsing
|
45
|
+
|
46
|
+
Parsing is implemented as replacing the original `initialize` method with one that converts the DER
|
47
|
+
encoded key to PEM, and then calls the original `initialize` method. This is because for some reason,
|
48
|
+
the built in `OpenSSL::PKey` object constructors can parse a PEM encoded PKCS8 key just fine, but it
|
49
|
+
blows up on a DER encoded key.
|
50
|
+
|
51
|
+
This provides a method `OpenSSL::PKey.pkcs8_parse` that parses the ASN.1 encoded key structure, extracts
|
52
|
+
the key type, and returns the correct `OpenSSL::PKey` object.
|
53
|
+
|
54
|
+
### Encoding
|
55
|
+
|
56
|
+
This provides a method `OpenSSL::PKey::{RSA,DSA,EC}.to_pkcs8` that encodes each key type into its correct
|
57
|
+
PKCS#8 format. The Ruby OpenSSL wrapper doesn't give you access to PKCS8 capabilities in OpenSSL, and even if
|
58
|
+
it did, not all versions of openssl that are packaged with ruby implement PKCS8 encoding.
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Keystores
|
2
2
|
|
3
3
|
This gem provides ruby implementations of different key stores. This was primarily created to provide the ability
|
4
|
-
to use many of the good Java key stores from ruby.
|
4
|
+
to use many of the good Java key stores from ruby. This gem adds the key stores to the OpenSSL module structure,
|
5
|
+
since that is where the `OpenSSL::PKCS12` keystore lives.
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -31,6 +32,8 @@ The certificate and key objects that these keystores return and expect are `Open
|
|
31
32
|
|
32
33
|
#### Java Key Store (jks) format
|
33
34
|
|
35
|
+
[Detailed documentation](JAVA_KEY_STORE_README.md)
|
36
|
+
|
34
37
|
##### Reading
|
35
38
|
|
36
39
|
This gem supports reading trusted certificate entries and private key entries. It can read
|
@@ -39,8 +42,8 @@ and decrypt RSA, DSA, and EC keys.
|
|
39
42
|
Example usage:
|
40
43
|
|
41
44
|
```
|
42
|
-
require 'keystores
|
43
|
-
keystore =
|
45
|
+
require 'keystores'
|
46
|
+
keystore = OpenSSL::JKS.new
|
44
47
|
|
45
48
|
# Load can take any IO object, or a path to a file
|
46
49
|
key_store_password = 'keystores'
|
data/keystores.gemspec
CHANGED
@@ -9,8 +9,9 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Ryan Larson']
|
10
10
|
spec.email = ['ryan.mango.larson@gmail.com']
|
11
11
|
|
12
|
-
spec.summary = 'This gem allows applications to interact with
|
13
|
-
spec.description =
|
12
|
+
spec.summary = 'This gem allows applications to interact with java key stores'
|
13
|
+
spec.description = 'This gem allows you to interact with java key stores in pure ruby. Keys and Certificates are' +
|
14
|
+
' represented as OpenSSL objects'
|
14
15
|
spec.homepage = 'https://github.com/rylarson/keystores'
|
15
16
|
spec.license = 'MIT'
|
16
17
|
|
data/lib/keystores.rb
CHANGED
@@ -13,6 +13,13 @@ module Keystores
|
|
13
13
|
class EncryptedPrivateKeyInfo
|
14
14
|
attr_accessor :encrypted_data, :algorithm, :encoded
|
15
15
|
|
16
|
+
# You can pass either an ASN.1 encryptedPrivateKeyInfo object
|
17
|
+
# or the encrypted bytes and the encryption algorithm.
|
18
|
+
#
|
19
|
+
# @param [Hash] opts
|
20
|
+
# @option opts [String] :encoded The ASN.1 encoded encrypted private key info
|
21
|
+
# @option opts [String] :algorithm The encryption algorithm
|
22
|
+
# @option opts [String] :encrypted_data The encrypted key bytes
|
16
23
|
def initialize(opts = {})
|
17
24
|
# Parses from encoded private key
|
18
25
|
if opts.has_key?(:encoded)
|
@@ -48,7 +48,8 @@ require 'keystores/jks/encrypted_private_key_info'
|
|
48
48
|
# Then concatenate the password with the recovered key, and compare with the
|
49
49
|
# last length(digest(p, P)) bytes of R. If they match, the recovered key is
|
50
50
|
# indeed the same key as the original key.
|
51
|
-
|
51
|
+
#
|
52
|
+
# TODO, implement this as an OpenSSL PBE Cipher
|
52
53
|
module Keystores
|
53
54
|
module Jks
|
54
55
|
class KeyProtector
|
@@ -47,7 +47,7 @@ module OpenSSL
|
|
47
47
|
#
|
48
48
|
# We currently ignore the optional parameters and publicKey fields.
|
49
49
|
# We encode the parameters are as part of the curve name,
|
50
|
-
# not in the private key structure.We do this because Java expects things
|
50
|
+
# not in the private key structure. We do this because Java expects things
|
51
51
|
# to be encoded this way
|
52
52
|
def encode_private_key
|
53
53
|
version = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new('1'))
|
@@ -141,7 +141,6 @@ module OpenSSL
|
|
141
141
|
# Parse the correct type of OpenSSL::PKey from a der encoded PKCS8 private key
|
142
142
|
def self.pkcs8_parse(der_bytes)
|
143
143
|
key_type = extract_key_type(der_bytes)
|
144
|
-
# pem = der_to_pem(der_bytes)
|
145
144
|
OpenSSL::PKey.const_get(key_type).new(der_bytes)
|
146
145
|
end
|
147
146
|
|
data/lib/keystores/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keystores
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Larson
|
@@ -66,7 +66,8 @@ dependencies:
|
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: This gem allows
|
69
|
+
description: This gem allows you to interact with java key stores in pure ruby. Keys
|
70
|
+
and Certificates are represented as OpenSSL objects
|
70
71
|
email:
|
71
72
|
- ryan.mango.larson@gmail.com
|
72
73
|
executables: []
|
@@ -77,6 +78,7 @@ files:
|
|
77
78
|
- .rspec
|
78
79
|
- .travis.yml
|
79
80
|
- Gemfile
|
81
|
+
- JAVA_KEY_STORE_README.md
|
80
82
|
- LICENSE.txt
|
81
83
|
- README.md
|
82
84
|
- Rakefile
|
@@ -111,5 +113,5 @@ rubyforge_project:
|
|
111
113
|
rubygems_version: 2.4.8
|
112
114
|
signing_key:
|
113
115
|
specification_version: 4
|
114
|
-
summary: This gem allows applications to interact with
|
116
|
+
summary: This gem allows applications to interact with java key stores
|
115
117
|
test_files: []
|