obfuskit 0.2.0 → 0.3.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.
- 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: []
|