obfuskit 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64dba62899b6d17faac7cb64e3797074bf7d532bda2ed2541b7eaf0a7e831be4
4
- data.tar.gz: eb181aeb2d05fffc68a2c7bc1229ed9524aa5bceebbf648e4ae80d342d8c3e52
3
+ metadata.gz: 4780130a4c77f313d5ecb10479d96b739fcdc6bcc1f7199bd847b27783b89848
4
+ data.tar.gz: f95871c0915fcf8cbacf5c02930bda78ed39cc2dee886450857b1cc72c7324b3
5
5
  SHA512:
6
- metadata.gz: 152431909ff9df68577645f73f68cb267662291b3e4ac8e13c95a34dd204718951a238f2d01c5d16d335a69083e79091e420b4103e0f6a35f151e0be8d09890d
7
- data.tar.gz: 3167acf2e668dc3fd4b5eb0a6d1b2d31f6f1d0eeaa98316f8375212baae9b56e0254b22a8a610d77d0b0238d2a832323734381dba8352d9df92e117e063f35ae
6
+ metadata.gz: a14410ebaad463c3672d1d18f447112e5e6180552977525d110b1c19ebd58a68e79685f4560849c9b86dca3573c13bb51ae98e1ea6939840045754037a8dd391
7
+ data.tar.gz: 87f6d65646ef72825b6bc3a4f75437ca6b26dd68ead31978ec0663bfac917669946a753ee026cfb053f4385947a1272cf9200b781ac8497461d5ff9d3664c1ea
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Martin Gratzer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # ObfusKit
2
+
3
+ ObfusKit is a ruby script to generate obfuscated secrets for `Swift` and `Kotlin`.
4
+
5
+ ## Installation and usage
6
+
7
+ Install the latest version of the gem using:
8
+
9
+ ```
10
+ gem install obfuskit
11
+ ```
12
+
13
+ To generate Swift code run the following command:
14
+
15
+ ```sh
16
+ obfuskit swift SECRET_1 SECRET_2 > generated.swift
17
+ ```
18
+
19
+ It will will create the file `generated.swift` containing an obfuscated version of the environment variables `SECRET_1` and `SECRET_2`.
20
+ This file should be excluded from the git repository and generated at build time.
21
+ The obfuscation salt is regenerated for each run.
22
+
23
+ ```swift
24
+ import Foundation
25
+
26
+ enum ObfusKit {
27
+ static let SECRET_1: String = _o.r([30, 113, 37, 119, 32, 37, 36])
28
+ static let SECRET_2: String = _o.r([24, 117, 35, 119, 38, 33, 34])
29
+
30
+ private class _3f3eccd2e5ea46b39738e5502bda6bef { }
31
+ private static let _o = O(String(describing: _3f3eccd2e5ea46b39738e5502bda6bef.self))
32
+ }
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) ?? "" } }
35
+ ```
36
+
37
+ The same concept applies for the `kotlin` language using:
38
+
39
+ ```sh
40
+ obfuskit kotlin com.myapp.configuration.environment SECRET_1 SECRET_2 > generated.kt
41
+ ```
42
+ It will create the Kotlin version `generated.kt`.
43
+
44
+ ```kotlin
45
+ package com.myapp.configuration.environment
46
+
47
+ object ObfusKit {
48
+ private val _o = O(_6572131328ef462d9d4a05cf4b2a2516::class.java.simpleName)
49
+ private class _6572131328ef462d9d4a05cf4b2a2516
50
+
51
+ val SECRET_1: String = _o.r(byteArrayOf(30, 116, 118, 115, 119, 119, 116))
52
+ val SECRET_2: String = _o.r(byteArrayOf(24, 112, 112, 115, 113, 115, 114))
53
+ }
54
+
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)}}
56
+
57
+ ```
58
+
59
+ ## Features
60
+ - [x] Generate Swift
61
+ - [x] Generate Kotlin
62
+ - [x] Read secrets from the Environment
63
+ - [x] Add dynamic salt for obfuscation
64
+ - [x] Support for .env files
65
+ - [ ] Use template engine for code generation
66
+ - [ ] Read secrets from 1Password CLI
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/exe/obfuskit ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'obfuskit/generator'
3
+ generator = Obfuskit::Generator.new
4
+ generator.generate()
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'obfuscator'
3
+ require 'securerandom'
4
+ require 'dotenv'
5
+
6
+ module Language
7
+ SWIFT = "Swift"
8
+ KOTLIN = "Kotlin"
9
+ end
10
+
11
+ module Obfuskit
12
+
13
+ class Generator
14
+
15
+ def generate()
16
+
17
+ Dotenv.load
18
+ args = ARGV
19
+ first_arg = args.shift
20
+
21
+ language_map = {
22
+ "swift" => Language::SWIFT,
23
+ "kotlin" => Language::KOTLIN,
24
+ "kt" => Language::KOTLIN
25
+ }
26
+
27
+ if first_arg != nil && language_map.key?(first_arg.downcase)
28
+
29
+ # Generate a random UUID and remove the hyphens
30
+ obfuscation_salt = SecureRandom.uuid.to_s.gsub("-", "")
31
+ # Create a new instance of the O class with the obfuscation salt
32
+ obfuscator = Obfuscator.new("_" + obfuscation_salt)
33
+
34
+ case language_map[first_arg]
35
+ when Language::SWIFT
36
+ puts generate_swift(args, obfuscator)
37
+ when Language::KOTLIN
38
+ puts generate_kotlin(args, obfuscator)
39
+ end
40
+ else
41
+ puts "First argument is not a valid language. Use `swift` or `kotlin`."
42
+ end
43
+ end
44
+
45
+ private
46
+ # Function to generate Swift code
47
+ def generate_swift(args, obfuscator)
48
+ # Start building the Swift code
49
+ code = "import Foundation\n\n"
50
+ code += "enum ObfusKit {\n"
51
+ # For each argument, if it's in the environment variables, add it to the code
52
+ args.each_with_index do |arg, index|
53
+ if ENV[arg] != nil
54
+ code += "\tstatic let #{arg}: String = _o.r(#{obfuscator.obfuscate(ENV[arg])})\n"
55
+ end
56
+ end
57
+ code += "\n"
58
+ # Add the obfuscation salt and the obfuscator to the code
59
+ code += <<-STRING
60
+ \tprivate class _#{obfuscator.salt} { }
61
+ \tprivate static let _o = O(String(describing: _#{obfuscator.salt}.self))
62
+ }\n\n
63
+ STRING
64
+
65
+ # Add the obfuscator source code to the code
66
+ code += '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) ?? "" } }'
67
+ # Return the generated code
68
+ return code
69
+ end
70
+
71
+ # Function to generate Kotlin code
72
+ def generate_kotlin(args, obfuscator)
73
+ # Get the first argument as the package name
74
+ package = args.shift
75
+ # If no package name is provided, return an empty string
76
+ if package == nil
77
+ puts "No package name provided."
78
+ return nil
79
+ end
80
+
81
+ # Start building the Kotlin code
82
+ code = "package #{package}\n\n"
83
+ code += "object ObfusKit {\n"
84
+ # Add the obfuscation salt and the obfuscator to the code
85
+ code += <<-STRING
86
+ \tprivate val _o = O(_#{obfuscator.salt}::class.java.simpleName)
87
+ \tprivate class _#{obfuscator.salt}\n
88
+ STRING
89
+
90
+ # For each argument, if it's in the environment variables, add it to the code
91
+ args.each_with_index do |arg, index|
92
+ if ENV[arg] != nil
93
+ code += "\tval #{arg}: String = _o.r(byteArrayOf(#{obfuscator.obfuscate(ENV[arg]).map { |i| i.to_s }.join(', ')}))\n"
94
+ end
95
+ end
96
+ code += "}\n\n"
97
+
98
+ # Add the obfuscator source code to the code
99
+ code += '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)}}'
100
+ # Return the generated code
101
+ return code
102
+ end
103
+
104
+ # Function to get the source code for the obfuscator
105
+ def obfuscator_source(file_name)
106
+ # Get the full path to the file
107
+ source_file_path = File.expand_path(file_name, __dir__)
108
+ # If the file exists, read and return its contents
109
+ return File.read(source_file_path) if File.exist?(source_file_path)
110
+ end
111
+ end
112
+
113
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A class representing an obfuscator.
4
+
5
+ module Obfuskit
6
+ class Obfuscator
7
+ # Initializes the obfuscator with a string.
8
+ # The string is converted to an array of bytes and stored in @c.
9
+ # The size of the array is stored in @l.
10
+ def initialize(salt)
11
+ salt = salt.bytes if salt.is_a? String
12
+ @salt = salt
13
+ @length = @salt.size
14
+ end
15
+
16
+ def salt
17
+ @salt
18
+ end
19
+
20
+ # Obfuscates a string.
21
+ # The string is converted to an array of bytes and each element is XORed with an element from @c.
22
+ # The index of the element from @c is the index of the element from the string modulo @l.
23
+ def obfuscate(value)
24
+ value.bytes.map.with_index { |b, i| b ^ @salt[i % @length] }
25
+ end
26
+
27
+ # Reverses the obfuscation of an array of bytes.
28
+ # Each element is XORed with an element from @c and the result is converted back to a string.
29
+ # The index of the element from @c is the index of the element from the array modulo @l.
30
+ def reveal(value)
31
+ value.map.with_index { |b, i| b ^ @salt[i % @length] }.pack('C*').force_encoding('utf-8')
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Obfuskit
4
+ VERSION = "0.1.2"
5
+ end
@@ -0,0 +1,10 @@
1
+ module Obfuskit
2
+ class Generator
3
+ def generate: -> void
4
+
5
+ private
6
+ def generate_kotlin: -> String
7
+ def generate_swift: -> String
8
+ def obfuscator_source: -> String
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module Obfuskit
2
+ class Obfuscator
3
+ @length: Int
4
+ @salt: String
5
+ def salt: -> String
6
+ end
7
+ end
data/sig/obfuskit.rbs ADDED
@@ -0,0 +1,3 @@
1
+ module Obfuskit
2
+ VERSION: String
3
+ end
metadata CHANGED
@@ -1,32 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obfuskit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Gratzer
8
- autorequire:
9
- bindir: bin
8
+ autorequire:
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-16 00:00:00.000000000 Z
11
+ date: 2024-01-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Environment variable obfuscation for Swift and Kotlin
13
+ description: Generate Swift and Kotlin files with obfuscated environment variables.
14
14
  email: mgratzer@gmail.com
15
15
  executables:
16
16
  - obfuskit
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - bin/obfuskit
21
- - lib/O.rb
22
- - lib/Omin.kt
23
- - lib/Omin.swift
24
- - lib/obfuskit.rb
20
+ - LICENSE.txt
21
+ - README.md
22
+ - Rakefile
23
+ - exe/obfuskit
24
+ - lib/obfuskit/generator.rb
25
+ - lib/obfuskit/obfuscator.rb
26
+ - lib/obfuskit/version.rb
27
+ - sig/obfuskit.rbs
28
+ - sig/obfuskit/generator.rbs
29
+ - sig/obfuskit/obfuscator.rbs
25
30
  homepage: https://github.com/mgratzer/obfuskit
26
31
  licenses:
27
32
  - MIT
28
- metadata: {}
29
- post_install_message:
33
+ metadata:
34
+ homepage_uri: https://github.com/mgratzer/obfuskit
35
+ post_install_message:
30
36
  rdoc_options: []
31
37
  require_paths:
32
38
  - lib
@@ -34,15 +40,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
34
40
  requirements:
35
41
  - - ">="
36
42
  - !ruby/object:Gem::Version
37
- version: '0'
43
+ version: 3.0.0
38
44
  required_rubygems_version: !ruby/object:Gem::Requirement
39
45
  requirements:
40
46
  - - ">="
41
47
  - !ruby/object:Gem::Version
42
48
  version: '0'
43
49
  requirements: []
44
- rubygems_version: 3.3.3
45
- signing_key:
50
+ rubygems_version: 3.5.3
51
+ signing_key:
46
52
  specification_version: 4
47
- summary: Environment variable obfuscation for Swift and Kotlin
53
+ summary: Environment variable obfuscation for Swift and Kotlin.
48
54
  test_files: []
data/bin/obfuskit DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'obfuskit'
data/lib/O.rb DELETED
@@ -1,25 +0,0 @@
1
- # A class representing an obfuscator.
2
- class O
3
- # Initializes the obfuscator with a string.
4
- # The string is converted to an array of bytes and stored in @c.
5
- # The size of the array is stored in @l.
6
- def initialize(s)
7
- s = s.bytes if s.is_a? String
8
- @c = s
9
- @l = @c.size
10
- end
11
-
12
- # Obfuscates a string.
13
- # The string is converted to an array of bytes and each element is XORed with an element from @c.
14
- # The index of the element from @c is the index of the element from the string modulo @l.
15
- def o(v)
16
- v.bytes.map.with_index { |b, i| b ^ @c[i % @l] }
17
- end
18
-
19
- # Reverses the obfuscation of an array of bytes.
20
- # Each element is XORed with an element from @c and the result is converted back to a string.
21
- # The index of the element from @c is the index of the element from the array modulo @l.
22
- def r(value)
23
- value.map.with_index { |b, i| b ^ @c[i % @l] }.pack('C*').force_encoding('utf-8')
24
- end
25
- end
data/lib/Omin.kt DELETED
@@ -1 +0,0 @@
1
- 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)}}
data/lib/Omin.swift DELETED
@@ -1 +0,0 @@
1
- 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) ?? "" } }
data/lib/obfuskit.rb DELETED
@@ -1,107 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Import the necessary modules and files
4
- require_relative 'O'
5
- require 'securerandom'
6
- require 'dotenv'
7
-
8
- # Define a module for language constants
9
- module Language
10
- SWIFT = "Swift"
11
- KOTLIN = "Kotlin"
12
- end
13
-
14
- # Function to generate Swift code
15
- def generate_swift(args)
16
- # Get the source code for the obfuscator
17
- obfuscator_source = obfuscator_source('Omin.swift')
18
- # Generate a random UUID and remove the hyphens
19
- obfuscation_salt = SecureRandom.uuid.to_s.gsub("-", "")
20
- # Create a new instance of the O class with the obfuscation salt
21
- o = O.new("_" + obfuscation_salt)
22
-
23
- # Start building the Swift code
24
- code = "import Foundation\n\n"
25
- code += "enum ObfusKit {\n"
26
- # For each argument, if it's in the environment variables, add it to the code
27
- args.each_with_index do |arg, index|
28
- if ENV[arg] != nil
29
- code += "\tstatic let #{arg}: String = _o.r(#{o.o(ENV[arg])})\n"
30
- end
31
- end
32
- code += "\n"
33
- # Add the obfuscation salt and the obfuscator to the code
34
- code += <<-STRING
35
- \tprivate class _#{obfuscation_salt} { }
36
- \tprivate static let _o = O(String(describing: _#{obfuscation_salt}.self))
37
- }\n\n
38
- STRING
39
-
40
- # Add the obfuscator source code to the code
41
- code += obfuscator_source
42
- # Return the generated code
43
- return code
44
- end
45
-
46
- # Function to generate Kotlin code
47
- def generate_kotlin(args)
48
- # Get the source code for the obfuscator
49
- obfuscator_source = obfuscator_source('Omin.kt')
50
- # Generate a random UUID and remove the hyphens
51
- obfuscation_salt = SecureRandom.uuid.to_s.gsub("-", "")
52
- # Create a new instance of the O class with the obfuscation salt
53
- o = O.new("_" + obfuscation_salt)
54
-
55
- # Start building the Kotlin code
56
- code = "object ObfusKit {\n"
57
- # Add the obfuscation salt and the obfuscator to the code
58
- code += <<-STRING
59
- \tprivate val _o = O(_#{obfuscation_salt}::class.java.simpleName)
60
- \tprivate class _#{obfuscation_salt}\n
61
- STRING
62
-
63
- # For each argument, if it's in the environment variables, add it to the code
64
- args.each_with_index do |arg, index|
65
- if ENV[arg] != nil
66
- code += "\tval #{arg}: String = _o.r(byteArrayOf(#{o.o(ENV[arg]).map { |i| i.to_s }.join(', ')}))\n"
67
- end
68
- end
69
- code += "}\n\n"
70
-
71
- # Add the obfuscator source code to the code
72
- code += obfuscator_source
73
- # Return the generated code
74
- return code
75
- end
76
-
77
- # Function to get the source code for the obfuscator
78
- def obfuscator_source(file_name)
79
- # Get the full path to the file
80
- source_file_path = File.expand_path(file_name, __dir__)
81
- # If the file exists, read and return its contents
82
- return File.read(source_file_path) if File.exist?(source_file_path)
83
- end
84
-
85
- # MAIN
86
-
87
- language_map = {
88
- "swift" => Language::SWIFT,
89
- "kotlin" => Language::KOTLIN,
90
- "kt" => Language::KOTLIN
91
- }
92
-
93
- Dotenv.load
94
-
95
- args = ARGV
96
- first_arg = args.shift
97
-
98
- if first_arg != nil && language_map.key?(first_arg.downcase)
99
- case language_map[first_arg]
100
- when Language::SWIFT
101
- puts generate_swift(args)
102
- when Language::KOTLIN
103
- puts generate_kotlin(args)
104
- end
105
- else
106
- puts "First argument is not a valid language. Use `swift` or `kotlin`."
107
- end