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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95df1da20d19fbbd42f0573e3373d1c08831f65f5a49365418fb98569a3d4c57
4
- data.tar.gz: 43964e64f7175109de2e033f538a1a42632ff4be5330fa30513fb53651f45a17
3
+ metadata.gz: 1bf83c6351238774e0cd0f479d2aeb033d6e06bf61a0567f461951c76ea2f551
4
+ data.tar.gz: b1ef6d097ab410c3266ea9ef97b7ee04dd6e9cee053f85d0cd2f3085e7dc6db0
5
5
  SHA512:
6
- metadata.gz: d2e3716d091ee82c00a397a2d17bd610220bef2678c0402e75582b81c8f5491915b0003196e4e72951aa29a3634eb30223b7c83463a31635f87a3e68c3f47600
7
- data.tar.gz: 3086262688ba6c838a649a9bcbef677578a6001d5a716748ff0974046f511a58e4e556cd127bc316edfe5bf4e41f4cfde3e5791e9a9b475a2ca5f8fd545c562d
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
- To generate Swift code run the following command:
12
+ Call `obfuskit -h` for help.
14
13
 
15
14
  ```sh
16
- obfuskit swift SECRET_1 SECRET_2 > generated.swift
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
- It will will create the file `generated.swift` containing an obfuscated version of the environment variables `SECRET_1` and `SECRET_2`.
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 SECRET_2 > generated.kt
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
- class O{private val a:ByteArray;private val b:Int;constructor(s:String){a=s.toByteArray(Charsets.UTF_8);b=a.size};fun o(v:String):ByteArray{val d=v.toByteArray(Charsets.UTF_8);return ByteArray(d.size){i->(d[i].toInt() xor a[i%b].toInt()).toByte()}};fun r(value:ByteArray):String{return String(ByteArray(value.size){i->(value[i].toInt() xor a[i%b].toInt()).toByte()},Charsets.UTF_8)}}
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
@@ -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
- Dotenv.load
19
- args = ARGV
20
- language_key = args.shift.downcase
15
+ parser = OptionsParser.new
16
+ options = parser.parse(ARGV)
21
17
 
22
- language_map = {
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 language_key != nil && language_map.key?(language_key)
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
- case language_map[language_key]
34
- when Language::SWIFT
35
- puts generate_swift(args, obfuscator)
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
- when Language::KOTLIN
38
- puts generate_kotlin(args, obfuscator)
33
+ else
34
+ STDERR.puts parser.parse(%w[--help])
39
35
  end
40
36
 
41
37
  else
42
- STDERR.puts "Please specify a valid language."
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 { |name|
65
- ENV[name] != nil ? [name, obfuscator.obfuscate(ENV[name])] : nil
66
- }.compact.to_h
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
- salt: obfuscator.salt
76
- )
56
+ type_name: type_name,
57
+ salt: obfuscator.salt,
58
+ )
77
59
  end
78
60
 
79
61
  end
@@ -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.bytes if salt.is_a? String
15
- @salt = salt
16
- @length = @salt.size
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 ^ @salt[i % @length] }
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 ^ @salt[i % @length] }.pack('C*').force_encoding('utf-8')
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 ObfusKit {
4
- private val _o = O(_6572131328ef462d9d4a05cf4b2a2516::class.java.simpleName)
5
- private class _6572131328ef462d9d4a05cf4b2a2516
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(', ') %>))
@@ -1,6 +1,6 @@
1
1
  import Foundation
2
2
 
3
- public enum ObfusKit {
3
+ public enum <%= type_name %> {
4
4
  <% values.each do |name, values| -%>
5
5
  public static let <%= name %>: String = _o.r([<%= values.map { |i| i.to_s }.join(', ') %>])
6
6
  <% end -%>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Obfuskit
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -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
@@ -1,10 +1,13 @@
1
1
  module Obfuskit
2
2
  class Obfuscator
3
- @length: Integer
4
- @salt: String
3
+ attr_reader salt: String
5
4
 
6
- def salt: -> String
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,6 @@
1
+ class OptionsParser
2
+ attr_reader options: ScriptOptions
3
+ attr_reader parser: OptionsParser
4
+
5
+ def parse: -> ScriptOptions
6
+ 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.2.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-01-19 00:00:00.000000000 Z
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.3
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: []