obfuskit 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +45 -10
- data/lib/obfuskit/generator.rb +24 -42
- data/lib/obfuskit/obfuscator.rb +5 -5
- data/lib/obfuskit/options_parser.rb +96 -0
- data/lib/obfuskit/templates/kotlin.erb +3 -3
- data/lib/obfuskit/templates/swift.erb +1 -1
- data/lib/obfuskit/version.rb +1 -1
- data/sig/obfuskit/generator.rbs +3 -3
- data/sig/obfuskit/obfuscator.rbs +6 -3
- data/sig/obfuskit/options_parser.rbs +6 -0
- data/sig/options_parser/script_options.rbs +20 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bf83c6351238774e0cd0f479d2aeb033d6e06bf61a0567f461951c76ea2f551
|
4
|
+
data.tar.gz: b1ef6d097ab410c3266ea9ef97b7ee04dd6e9cee053f85d0cd2f3085e7dc6db0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf47193804ca3fa28838b8d33d5f8e05965665c354b94a5651d8ca7e0ce0b9515758f84571664351efeae009116dc4fc9363bc28f1599ccdd3d1e1d0506c3e8f
|
7
|
+
data.tar.gz: 0a809262ff81d7c6df8656088867f575003ff519e521bdc3db38a775295a938d9ca05d4834c3bb6432151d1fc33d169d8810a51a8013a20b76f58c893490b804
|
data/README.md
CHANGED
@@ -1,22 +1,36 @@
|
|
1
1
|
# ObfusKit
|
2
|
-
|
3
|
-
ObfusKit is a ruby script to generate obfuscated secrets for `Swift` and `Kotlin`.
|
2
|
+
ObfusKit is a ruby script that generates obfuscated secrets for `Swift` and `Kotlin`.
|
4
3
|
|
5
4
|
## Installation and usage
|
6
5
|
|
7
6
|
Install the latest version of the gem using:
|
8
7
|
|
9
|
-
```
|
8
|
+
```sh
|
10
9
|
gem install obfuskit
|
11
10
|
```
|
12
11
|
|
13
|
-
|
12
|
+
Call `obfuskit -h` for help.
|
14
13
|
|
15
14
|
```sh
|
16
|
-
obfuskit
|
15
|
+
Usage: obfuskit [options]
|
16
|
+
|
17
|
+
Specific options:
|
18
|
+
-l, --language [LANGUAGE] Output language (swift, kotlin). Kotlin requires a package parameter.
|
19
|
+
-k SECRET_1,SECRET_2,SECRET_3, List of environment variable keys
|
20
|
+
--keys
|
21
|
+
-p, --package [PACKAGE] Package name for Kotlin
|
22
|
+
-t, --type [TYPE] Output type name. Defaults to `ObfusKit`
|
23
|
+
-e, --env [PATH] Path to an alternative .env file
|
24
|
+
|
25
|
+
Common options:
|
26
|
+
-h, --help Show this message
|
27
|
+
-v, --version Show version
|
17
28
|
```
|
18
29
|
|
19
|
-
|
30
|
+
### Swift
|
31
|
+
|
32
|
+
To generate Swift code run the following command:
|
33
|
+
It will create the file `generated.swift` containing an obfuscated version of the environment variables `SECRET_1` and `SECRET_2`.
|
20
34
|
This file should be excluded from the git repository and generated at build time.
|
21
35
|
The obfuscation salt is regenerated for each run.
|
22
36
|
|
@@ -30,14 +44,15 @@ enum ObfusKit {
|
|
30
44
|
private class _3f3eccd2e5ea46b39738e5502bda6bef { }
|
31
45
|
private static let _o = O(String(describing: _3f3eccd2e5ea46b39738e5502bda6bef.self))
|
32
46
|
}
|
33
|
-
|
34
|
-
struct O { private let c: [UInt8]; private let l: Int; init(_ s: String) { self.init([UInt8](s.utf8)) }; init(_ c: [UInt8]) { self.c = c; l = c.count }; @inline(__always) func o(_ v: String) -> [UInt8] { [UInt8](v.utf8).enumerated().map { $0.element ^ c[$0.offset % l] } }; @inline(__always) func r(_ value: [UInt8]) -> String { String(bytes: value.enumerated().map { $0.element ^ c[$0.offset % l] }, encoding: .utf8) ?? "" } }
|
47
|
+
// ...
|
35
48
|
```
|
36
49
|
|
50
|
+
### Kotlin
|
51
|
+
|
37
52
|
The same concept applies for the `kotlin` language using:
|
38
53
|
|
39
54
|
```sh
|
40
|
-
obfuskit kotlin com.myapp.configuration.environment SECRET_1
|
55
|
+
obfuskit -l kotlin -p com.myapp.configuration.environment -k SECRET_1,SECRET_2 > generated.kt
|
41
56
|
```
|
42
57
|
It will create the Kotlin version `generated.kt`.
|
43
58
|
|
@@ -51,9 +66,29 @@ object ObfusKit {
|
|
51
66
|
val SECRET_1: String = _o.r(byteArrayOf(30, 116, 118, 115, 119, 119, 116))
|
52
67
|
val SECRET_2: String = _o.r(byteArrayOf(24, 112, 112, 115, 113, 115, 114))
|
53
68
|
}
|
69
|
+
// ...
|
70
|
+
```
|
71
|
+
|
72
|
+
## Customizations
|
54
73
|
|
55
|
-
|
74
|
+
### The output type name
|
56
75
|
|
76
|
+
The default generated type name in the target language is `ObfusKit``. Customize this name with the `-t` option.
|
77
|
+
Which will generate the Swift type `Secrets` instead of `ObfusKit`.
|
78
|
+
|
79
|
+
```swift
|
80
|
+
import Foundation
|
81
|
+
|
82
|
+
enum Secrets {
|
83
|
+
// ..
|
84
|
+
```
|
85
|
+
|
86
|
+
### Use a custom .env file location
|
87
|
+
|
88
|
+
Use the `-e` option to define the path to a different `.env` file, e.g. if you want to reuse the `fastlane/.env` file.
|
89
|
+
|
90
|
+
```sh
|
91
|
+
obfuskit -l swift -k SECRET_3,SECRET_4 -e fastlane/.env > generated.swift
|
57
92
|
```
|
58
93
|
|
59
94
|
## Features
|
data/lib/obfuskit/generator.rb
CHANGED
@@ -1,79 +1,61 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require_relative 'obfuscator'
|
3
|
+
require_relative 'options_parser'
|
3
4
|
require 'securerandom'
|
4
5
|
require 'dotenv'
|
5
6
|
require 'erb'
|
6
|
-
|
7
|
-
module Language
|
8
|
-
SWIFT = "Swift"
|
9
|
-
KOTLIN = "Kotlin"
|
10
|
-
end
|
7
|
+
require 'optparse'
|
11
8
|
|
12
9
|
module Obfuskit
|
13
10
|
|
14
11
|
class Generator
|
15
12
|
|
16
|
-
def generate
|
13
|
+
def generate
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
language_key = args.shift.downcase
|
15
|
+
parser = OptionsParser.new
|
16
|
+
options = parser.parse(ARGV)
|
21
17
|
|
22
|
-
|
23
|
-
"swift" => Language::SWIFT,
|
24
|
-
"kotlin" => Language::KOTLIN,
|
25
|
-
"kt" => Language::KOTLIN
|
26
|
-
}
|
18
|
+
Dotenv.load(options.dot_env_file_path)
|
27
19
|
|
28
|
-
if
|
20
|
+
if !options.output_language.nil? && options.env_var_keys.length.positive?
|
29
21
|
|
30
22
|
salt = SecureRandom.uuid.to_s.gsub("-", "")
|
31
23
|
obfuscator = Obfuscator.new("_" + salt)
|
32
24
|
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
values = obfuscated_values_from_env(options.env_var_keys, obfuscator)
|
26
|
+
|
27
|
+
if options.output_language == :swift
|
28
|
+
puts generate_with_template("swift", values, nil, options.output_type_name, obfuscator)
|
29
|
+
|
30
|
+
elsif options.output_language == :kotlin && !options.package_name.nil?
|
31
|
+
puts generate_with_template("kotlin", values, options.package_name, options.output_type_name, obfuscator)
|
36
32
|
|
37
|
-
|
38
|
-
|
33
|
+
else
|
34
|
+
STDERR.puts parser.parse(%w[--help])
|
39
35
|
end
|
40
36
|
|
41
37
|
else
|
42
|
-
STDERR.puts
|
38
|
+
STDERR.puts parser.parse(%w[--help])
|
43
39
|
end
|
44
40
|
end
|
45
41
|
|
46
42
|
private
|
47
43
|
|
48
|
-
def generate_swift(args, obfuscator)
|
49
|
-
values = obfuscated_values_from_env(args, obfuscator)
|
50
|
-
generate_with_template("swift", values, nil, obfuscator)
|
51
|
-
end
|
52
|
-
|
53
|
-
def generate_kotlin(args, obfuscator)
|
54
|
-
package = args.shift
|
55
|
-
if package == nil
|
56
|
-
STDERR.puts "No package name provided."
|
57
|
-
else
|
58
|
-
values = obfuscated_values_from_env(args, obfuscator)
|
59
|
-
generate_with_template("kotlin", values, package, obfuscator)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
44
|
def obfuscated_values_from_env(args, obfuscator)
|
64
|
-
args.map
|
65
|
-
ENV[name]
|
66
|
-
|
45
|
+
args.map do |name|
|
46
|
+
!ENV[name].nil? ? [name, obfuscator.obfuscate(ENV[name])] : nil
|
47
|
+
end.compact.to_h
|
67
48
|
end
|
68
49
|
|
69
|
-
def generate_with_template(template_name, values, package, obfuscator)
|
50
|
+
def generate_with_template(template_name, values, package, type_name, obfuscator)
|
70
51
|
file = File.expand_path("templates/#{template_name}.erb", __dir__)
|
71
52
|
template = ERB.new(File.read(file), trim_mode: "-")
|
72
53
|
template.result_with_hash(
|
73
54
|
values: values,
|
74
55
|
package: package,
|
75
|
-
|
76
|
-
|
56
|
+
type_name: type_name,
|
57
|
+
salt: obfuscator.salt,
|
58
|
+
)
|
77
59
|
end
|
78
60
|
|
79
61
|
end
|
data/lib/obfuskit/obfuscator.rb
CHANGED
@@ -11,23 +11,23 @@ module Obfuskit
|
|
11
11
|
# The string is converted to an array of bytes and stored in @c.
|
12
12
|
# The size of the array is stored in @l.
|
13
13
|
def initialize(salt)
|
14
|
-
salt = salt
|
15
|
-
@
|
16
|
-
@
|
14
|
+
@salt = salt || ""
|
15
|
+
@salt_bytes = (salt.bytes || []) if salt.is_a? String
|
16
|
+
@salt_length = @salt_bytes.size
|
17
17
|
end
|
18
18
|
|
19
19
|
# Obfuscates a string.
|
20
20
|
# The string is converted to an array of bytes and each element is XORed with an element from @c.
|
21
21
|
# The index of the element from @c is the index of the element from the string modulo @l.
|
22
22
|
def obfuscate(value)
|
23
|
-
value.bytes.map.with_index { |b, i| b ^ @
|
23
|
+
value.bytes.map.with_index { |b, i| b ^ @salt_bytes[i % @salt_length] }
|
24
24
|
end
|
25
25
|
|
26
26
|
# Reverses the obfuscation of an array of bytes.
|
27
27
|
# Each element is XORed with an element from @c and the result is converted back to a string.
|
28
28
|
# The index of the element from @c is the index of the element from the array modulo @l.
|
29
29
|
def reveal(value)
|
30
|
-
value.map.with_index { |b, i| b ^ @
|
30
|
+
value.map.with_index { |b, i| b ^ @salt_bytes[i % @salt_length] }.pack('C*').force_encoding('utf-8')
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
class OptionsParser
|
5
|
+
class ScriptOptions
|
6
|
+
|
7
|
+
attr_accessor :output_language, :env_var_keys, :package_name, :output_type_name, :dot_env_file_path
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.output_language = nil
|
11
|
+
self.env_var_keys = []
|
12
|
+
self.package_name = nil
|
13
|
+
self.output_type_name = "ObfusKit"
|
14
|
+
self.dot_env_file_path = ".env"
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_options(parser)
|
18
|
+
parser.banner = "Usage: obfuskit [options]"
|
19
|
+
parser.separator ""
|
20
|
+
parser.separator "Specific options:"
|
21
|
+
|
22
|
+
# add additional options
|
23
|
+
output_language_option(parser)
|
24
|
+
env_var_keys_option(parser)
|
25
|
+
package_name_option(parser)
|
26
|
+
output_type_name_option(parser)
|
27
|
+
dot_env_file_path_options(parser)
|
28
|
+
|
29
|
+
parser.separator ""
|
30
|
+
parser.separator "Common options:"
|
31
|
+
# No argument, shows at tail. This will print an options summary.
|
32
|
+
# Try it and see!
|
33
|
+
parser.on_tail("-h", "--help", "Show this message") do
|
34
|
+
puts parser
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
|
38
|
+
# Another typical switch to print the version.
|
39
|
+
parser.on_tail("-v", "--version", "Show version") do
|
40
|
+
puts Obfuskit::VERSION
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def output_language_option(parser)
|
49
|
+
parser.on("-l", "--language [LANGUAGE]", [:swift, :kotlin],
|
50
|
+
"Output language (swift, kotlin). Kotlin requires a package parameter.") do |t|
|
51
|
+
self.output_language = t
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def env_var_keys_option(parser)
|
56
|
+
parser.on("-k", "--keys SECRET_1,SECRET_2,SECRET_3", Array, "List of environment variable keys") do |list|
|
57
|
+
self.env_var_keys = list
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def package_name_option(parser)
|
62
|
+
parser.on("-p", "--package [PACKAGE]", "Package name for Kotlin") do |value|
|
63
|
+
self.package_name = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def output_type_name_option(parser)
|
68
|
+
parser.on("-t", "--type [TYPE]", "Output type name. Defaults to `ObfusKit`") do |value|
|
69
|
+
self.output_type_name = value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def dot_env_file_path_options(parser)
|
74
|
+
parser.on("-e", "--env [PATH]", "Path to an alternative .env file") do |value|
|
75
|
+
self.dot_env_file_path = value
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Return a structure describing the options.
|
82
|
+
#
|
83
|
+
def parse(args)
|
84
|
+
# The options specified on the command line will be collected in
|
85
|
+
# *options*.
|
86
|
+
|
87
|
+
@options = ScriptOptions.new
|
88
|
+
OptionParser.new do |parser|
|
89
|
+
@options.define_options(parser)
|
90
|
+
parser.parse!(args)
|
91
|
+
end
|
92
|
+
@options
|
93
|
+
end
|
94
|
+
|
95
|
+
attr_reader :parser, :options
|
96
|
+
end # class OptionsParser
|
@@ -1,8 +1,8 @@
|
|
1
1
|
package <%= package %>
|
2
2
|
|
3
|
-
public object
|
4
|
-
private val _o = O(
|
5
|
-
private class
|
3
|
+
public object <%= type_name %> {
|
4
|
+
private val _o = O(<%= salt %>::class.java.simpleName)
|
5
|
+
private class <%= salt %>
|
6
6
|
|
7
7
|
<% values.each do |name, values| -%>
|
8
8
|
public val <%= name %>: String = _o.r(byteArrayOf(<%= values.map { |i| i.to_s }.join(', ') %>))
|
data/lib/obfuskit/version.rb
CHANGED
data/sig/obfuskit/generator.rbs
CHANGED
@@ -3,9 +3,9 @@ module Obfuskit
|
|
3
3
|
def generate: -> void
|
4
4
|
|
5
5
|
private
|
6
|
-
def generate_kotlin: ([String], Obfuscator) -> String
|
7
|
-
def generate_swift: ([String], Obfuscator) -> String
|
6
|
+
def generate_kotlin: ([String], String, Obfuscator) -> String
|
7
|
+
def generate_swift: ([String], String, Obfuscator) -> String
|
8
8
|
def obfuscated_values_from_env: ([String], Obfuscator) -> Hash[String, [Integer]]
|
9
|
-
def generate_with_template: (String, Hash[String, [Integer]], String, Obfuscator) -> String
|
9
|
+
def generate_with_template: (String, Hash[String, [Integer]], String?, String, Obfuscator) -> String
|
10
10
|
end
|
11
11
|
end
|
data/sig/obfuskit/obfuscator.rbs
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
module Obfuskit
|
2
2
|
class Obfuscator
|
3
|
-
|
4
|
-
@salt: String
|
3
|
+
attr_reader salt: String
|
5
4
|
|
6
|
-
def salt: ->
|
5
|
+
def initialize: (salt: String) -> void
|
7
6
|
def obfuscate: (String) -> [Integer]
|
8
7
|
def reveal: ([Integer]) -> String
|
8
|
+
|
9
|
+
private
|
10
|
+
attr_reader salt_length: Integer
|
11
|
+
attr_reader salt_bytes: [Integer]
|
9
12
|
end
|
10
13
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OptionsParser
|
2
|
+
class ScriptOptions
|
3
|
+
attr_accessor dot_env_file_path: String
|
4
|
+
attr_accessor dot_env_file_paths: [String]
|
5
|
+
attr_accessor env_var_keys: [String]
|
6
|
+
attr_accessor output_language: String?
|
7
|
+
attr_accessor output_type_name: String
|
8
|
+
attr_accessor package_name: String?
|
9
|
+
|
10
|
+
def define_options: -> void
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def dot_env_file_path_options: -> OptionParser
|
15
|
+
def env_var_keys_option: -> OptionParser
|
16
|
+
def output_language_option: -> OptionParser
|
17
|
+
def output_type_name_option: -> OptionParser
|
18
|
+
def package_name_option: -> OptionParser
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: obfuskit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Gratzer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Generate Swift and Kotlin files with obfuscated environment variables.
|
14
14
|
email: mgratzer@gmail.com
|
@@ -23,18 +23,21 @@ files:
|
|
23
23
|
- exe/obfuskit
|
24
24
|
- lib/obfuskit/generator.rb
|
25
25
|
- lib/obfuskit/obfuscator.rb
|
26
|
+
- lib/obfuskit/options_parser.rb
|
26
27
|
- lib/obfuskit/templates/kotlin.erb
|
27
28
|
- lib/obfuskit/templates/swift.erb
|
28
29
|
- lib/obfuskit/version.rb
|
29
30
|
- sig/obfuskit.rbs
|
30
31
|
- sig/obfuskit/generator.rbs
|
31
32
|
- sig/obfuskit/obfuscator.rbs
|
33
|
+
- sig/obfuskit/options_parser.rbs
|
34
|
+
- sig/options_parser/script_options.rbs
|
32
35
|
homepage: https://github.com/mgratzer/obfuskit
|
33
36
|
licenses:
|
34
37
|
- MIT
|
35
38
|
metadata:
|
36
39
|
homepage_uri: https://github.com/mgratzer/obfuskit
|
37
|
-
post_install_message:
|
40
|
+
post_install_message:
|
38
41
|
rdoc_options: []
|
39
42
|
require_paths:
|
40
43
|
- lib
|
@@ -49,8 +52,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
52
|
- !ruby/object:Gem::Version
|
50
53
|
version: '0'
|
51
54
|
requirements: []
|
52
|
-
rubygems_version: 3.5.
|
53
|
-
signing_key:
|
55
|
+
rubygems_version: 3.5.6
|
56
|
+
signing_key:
|
54
57
|
specification_version: 4
|
55
58
|
summary: Environment variable obfuscation for Swift and Kotlin.
|
56
59
|
test_files: []
|