obfuskit 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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