Noka/Infinity Encryption – Version 1.00.00 – Ruby

Advertisement

# THIS CODE IS STILL BEING TRANSLATE AND NOT READY FOR PRODUCTION SOME OF IT DESIGN MAY
# CHANGE SO THAT IT CAN BE RELEASED AS A GEM

###########################################################################################
#                                                                                         #
#    Copyright 2018 Khang H. Nguyen (kevinhg86)                                           #
#    E-mail: kevin@fai.host | Web: http://kevinhng86.iblog.website                        #
#    Contributors: https://github.com/kevinhng86/noka-encryption/blob/master/CONTRIBUTORS #                                                    #
#                                                                                         #    
#                                                                                         #
#    Permission is hereby granted, free of charge, to any person obtaining a copy         #
#    of this software and associated documentation files (the "Software"), to deal        #
#    in the Software without restriction, including without limitation the rights         #
#    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies     #
#    of the Software, and to permit persons to whom the Software is furnished             # 
#    to do so, subject to the following conditions:                                       #
#                                                                                         #
#    The above copyright notice and this permission notice shall be  included in all      #
#    copies or substantial portions of the Software.                                      #
#                                                                                         #
#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR           #
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,             #
#    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL              #
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER           #
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,        #
#    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN            #
#    THE SOFTWARE.                                                                        #
#                                                                                         #
###########################################################################################

class Noka_Encryption
    
    begin
        require 'bcrypt'
        @@bcrypt = true
    rescue LoadError
        @@bcrypt = false
    end
    
    # Version number.
    @@version = '1.00.00'

    # This is the default algo for the hash() function if none was inputted. It also used by nk_hashc() and nk_hash() function.
    @@default_hash_algo = 'sha512'

    # This is used by the nk_hashc() and nk_hash() function.
    @@default_hash_key = '787f353e9aed9891ce8e5e06c7677d9b7f744f339c330e069c3aad3b62c85e30'

    # This is the default algo for the crypt() function. It also used by the nk_hashc() function.
    # sha512/sha256/blowfish
    default_crypt_algo = 'sha512'

    # This is the encryption algo that is used by the nk_hash(), nk_hashc(), and encrypt() function.
    @@default_encr_algo = 'aes-256-ctr'

    # This is the default encryption key that is used by the nk_hash() and nk_hashc(), and encrypt() function.
    @default_encr_key = '07ea0b59140f53ae1a11a01313c2bddec90f2158459a9cfb26c57fd3c7564fed'

    # This array of algo name is used by nk_hashc(), nk_hash(), and hashx() function. Each function
    # required a different amount of algorithms. However, for them all to work, there must
    # at least 3 algorithms that are defined in this array.
    @@hash_algos = [ 'ripemd320',
                     'gost',
                     'haval256,5',
                   ]

    # This array of keys is used by nk_hashc(), nk_hash(), and hashx() function. Each function
    # required a different amount of keys. However, for them all to work, there must
    # at least 3 kyes that are defined in this array.
    @@hash_keys = [ '98c9b9afeb5774f0410505b2825d460e2af6cbef01dfd0ff21287ae93e916b70',
                    '8e2bbe0f642d4621a0a4976a82a531b06a4dc6941fbd7212f1225a60385c3347',
                    'be1ae0e606539a935ab92d110513bbbab6cba5d7baa3ef8f2646b99af285e0b9',
                  ]

    # All password that is going to be hashed need to be pad to the maximum allowable password's length.
    # This is to prevent timing guesses. This string is premade to save time and also make guessing the password's length
    # base on script execution time is almost an impossible task. Thus, this string must be as long as the maximum
    # allowable password length. Also, this pad string can't be random as we need to verify the hash later.
    @@pwd_pad_str = ')skvUtURrzhyY2@^nVZ`^1QwK8F8eK9b4^xym$@E'

    # Maximum allowable password length.
    @@pwd_len_max = 40

    # Default encryption round used by nk_encryption.
    @@encr_rounds = 7

    # Algos that will be utilized by nk_encryption.
    @@encr_algos = ['aes-256-xts', 'bf-ecb', 'aes-256-ctr', 'camellia-256-cbc', 'aes-128-cbc', 'aes-192-cbc', 'aes-192-ecb']

    # Keys that will be used by nk_encryption.
    @@encr_keys = [ '1451b406352fc73cf9fa522d1400f0cae932ff4a7d36c492e08f1d92e31ed718',
                    '67d40dcbb9183c4d5ebc4afc4d6c35bd835c295ef0d9b949255baad7277d8016',
                    'bdd78331a3c1c8de11509cd001db78f365f835201057dda53e36fea060670558',
                    '266b1659c1c402a5c35e308012413991a9cb0a14c3db2ddea71934a63d177a17',
                    '82be74af2a541bd1aeefdb2c12ec76f0',
                    'd7b7921cca7ff0bda12852e1020913312051666b24ae4c71',
                    '657df124b460a7a974953a8a8fa36566e15784214f7ee145'
                  ]

    # Separator used for joining strings for the nk_hashc(), nk_hash(), scramble(), and the descramble() function.
    # A separator must be a one character and must not be a hexadecimal digits(a-f, A-F, and 0-9).
    @@sep = '|'

    # Configuration of the scrambler.
    @@scramble = { 'random_min' => 3, 'random_max' => 9,
                   'original_min' => 3, 'original_max' => 9,
                   'char_from' => 1, 'char_to' => 255,
                   'min_char' => 15,
                 }

    # If hex_detect_key is set to true then keys that consisted of hexadecimal digits and with their length divisble by two will be convert
    # from hexadecimal to binary. hex_detect_key only accept a true or a false value. Any other's values will make all the functions
    # return a false value. This is to prevent mistake in placement of value.
    # To override hex_detect_key as the function level, pass a false value or a true value to the
    # hex_detect_key argument(if available) instead of a null value.
    @@hex_detect_key = true

    # Future planned usage where if debug mode is on if there is a mistake in input an error will be thrown instead of returning a boolean false.
    @@debug = false

    def random_salt_blowfish
        
        salt_pre = '$2a$'
        salt_low = 4
        salt_high = 9
        salt_char = '0123456789abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./'
        salt_char_length = salt_char.length
        salt_length = 22
        salt_two_digit_cost = rand( salt_low..salt_high )
        salt_two_digit_cost = "0" << salt_two_digit_cost.to_s if salt_two_digit_cost < 10
        str = salt_pre << salt_two_digit_cost << '$'

        for i in 0...salt_length
            str << salt_char[ rand(0...salt_char_length)]
        end

        return str
    end

    def random_salt_sha512

        salt_char = '0123456789abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        salt_char_length = salt_char.length
        min = 5000
        max = 10000
        len = 16
        str = '$6$rounds=' << rand( min..max ).to_s << '$'
        
        for i in 0...len
            str << salt_char[ rand(0...salt_char_length) ]
        end
    
        return str << '$'
    end
    
    def random_salt_sha256

        salt_char = '0123456789abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        salt_char_length = salt_char.length
        min = 5000
        max = 10000
        len = 16
        str = '$5$rounds=' << rand( min..max ).to_s << '$'
     
        for i in 0...len
            str << salt_char[ rand(0...salt_char_length) ] 
        end
    
        return str << '$'
    end
    
    def crypt( password , algo = nil )

        algo ||= @@default_crypt_algo

        return false if !self.chk_str(password, 1)
        return false if !algo.kind_of? String

        algo = algo.downcase
                        
        if algo === 'blowfish'
            raise ArgumentError, 'crypt(): bcrypt library is not install.' if @@bcrypt === false
            salt = self.random_salt_blowfish
        elsif algo === 'sha256' 
            salt = self.random_salt_sha256
        elsif algo === 'sha512'
            salt = self.random_salt_sha512
        else
            return false
        end
        
        output = algo === 'blowfish'? BCrypt::Engine.hash_secret( password, salt ) : password.crypt( salt )
        
        return output.length > 0 && output != '*0'? output : false
    end
    
    def scramble ( str, args = nil )

        ceil = 255

        args ||= {} 

        return false if !args.kind_of? Hash
        return false if !str.kind_of? String
        return false if (len = str.length) < 1

        args['min_char'] ||= @@scramble['min_char']  
        args['random_min'] ||= @@scramble['random_min'] 
        args['random_max'] ||= @@scramble['random_max'] 
        args['original_min'] ||= @@scramble['original_min'] 
        args['original_max'] ||= @@scramble['original_max'] 
        args['char_from'] ||= @@scramble['char_from'] 
        args['char_to'] ||= @@scramble['char_to'] 

        return false if !self.chk_int( args['min_char'], 1 ) 
        return false if !self.chk_int( args['random_min'], 1, 255 )
        return false if !self.chk_int( args['random_max'], 1, 255 )
        return false if !self.chk_int( args['original_min'], 1, 255 ) 
        return false if !self.chk_int( args['original_max'], 1, 255 )
        return false if !self.chk_int( args['char_from'], 1, 255 )
        return false if !self.chk_int( args['char_to'], 1, 255 )

        return false if args['original_max'] < args['original_min']
        return false if args['random_max'] < args['random_min'] 
        return false if args['char_to'] < args['char_from'] 
        return false if args['min_char'] + args['original_max'] > ceil
 
        padded = 1
        pad_str = ''
        blk_random = rand( 1..255 )
        blk_original = rand( 1..255 )
        mode = rand( 1..255 );
        output = self.chr( blk_random ) << self.chr( blk_original ) << self.chr( mode )
        blk_random = args['random_min'] + blk_random % (args['random_max'] + 1 - args['random_min'])
        blk_original = args['original_min'] + blk_original % (args['original_max'] + 1 - args['original_min']);

        if args.has_key? 'mode'
            return false if !self.chk_int(args['mode'], 0, 3)
            mode = [ args['mode'], 
                     mode % 2 === 0
                   ]
        else
            mode = [ 0 + mode % (3 + 1 - 0), 
                      mode % 2 === 0
                   ]
        end

        if mode[1] === true
        
            while len < args['min_char']
                str << self.chr( rand(args['char_from']..args['char_to']) )
                padded += 1
                len += 1
            end

            while len % blk_original != 0
                str << self.chr( rand(args['char_from']..args['char_to']) )
                padded += 1
                len += 1
            end
     
        else
        
            while len < args['min_char']
                pad_str << self.chr( rand(args['char_from']..args['char_to']) )
                padded += 1
                len += 1
            end
        
            while len % blk_original != 0
                pad_str << self.chr( rand(args['char_from']..args['char_to']) )
                padded += 1
                len += 1
            end
        
            str = pad_str << str
        end

        str = self.split( str, blk_original )

        if mode[0] === 0

            for i in 0...str.length
                pad_str = ''
                ind = 0

                while ind < blk_random
                    pad_str << self.chr( rand(args['char_from']..args['char_to']) )
                    ind += 1
                end
            
                str[i] = pad_str << str[i]
            end
        
        elsif mode[0] === 1 
        
            for i in 0...str.length
                pad_str = ''
                ind = 0

                while ind < blk_random 
                    pad_str << self.chr( rand(args['char_from']..args['char_to']) )
                    ind += 1
                end
            
                str[i] << pad_str
            end

        elsif mode[0] === 2

            for i in 0...str.length
                pad_str = ''
                ind = 0

                while ind < blk_random
                    pad_str << self.chr( rand(args['char_from']..args['char_to']) )
                    ind += 1
                end
            
                if ( i % 2 === 0 )
                    str[i] << pad_str
                else
                    str[i] = pad_str << str[i].reverse
                end
            end

        elsif mode[0] === 3
        
            _next = mode[1]

            for i in 0...str.length 
                pad_str = ''
                ind = 0

                while ind < blk_random 
                    pad_str << self.chr( rand(args['char_from']..args['char_to']) )
                    ind += 1
                end
            
                if _next === true
                    _next = self.ord( pad_str[0] ) % 2 === 0
                    str[i] << pad_str
                else
                    _next = self.ord( pad_str[0] ) % 2 === 0
                    str[i] = pad_str << str[i].reverse
                end
            
            end
        
        end

        output << self.chr( padded ) << str.join

        return output    
    end
    
    def descramble ( str, args = nil )
    
        ceil = 255
    
        args ||= {}
        raise ArgumentError, 'descramble(): args must be an array' if !args.kind_of? Hash 
        raise ArgumentError, 'descramble(): str must be a string with a length of at least 5.' if !self.chk_str( str, 5)

        args['random_min'] ||= @@scramble['random_min']
        args['random_max'] ||= @@scramble['random_max']
        args['original_min'] ||= @@scramble['original_min']
        args['original_max'] ||= @@scramble['original_max']
    
        raise ArgumentError, 'descramble(): args["random_min"] must be an integer with a value between 1 and 255.' if !self.chk_int( args['random_min'], 1, 255 )
        raise ArgumentError, 'descramble(): args["random_max"] must be an integer with a value between 1 and 255.' if !self.chk_int( args['random_max'], 1, 255 )
        raise ArgumentError, 'descramble(): args["original_min"] must be an integer with a value between 1 and 255.' if !self.chk_int( args['original_min'], 1, 255 )
        raise ArgumentError, 'descramble(): args["original_max"] must be an integer with a value between 1 and 255.' if !self.chk_int( args['original_max'], 1, 255 )

        raise ArgumentError, 'descramble(): args["original_min"] can\' be larger than args["original_max"].' if args['original_max'] < args['original_min']
        raise ArgumentError, 'descramble(): args["random_min"] can\' be larger than args["random_max"].' if args['random_max'] < args['random_min']

        blk_random = args['random_min'] + self.ord( str[0] ) % (args['random_max'] + 1 - args['random_min'])
        blk_original = args['original_min'] + self.ord( str[1] ) % (args['original_max'] + 1 - args['original_min'])
                 
        if args.has_key? 'mode' 
            raise ArgumentError, 'descramble(): args["mode"] must be an integer with a value between 0 and 3, or not set.' if !self.chk_int(args['mode'], 0, 3)
            mode = [ args['mode'], 
                     self.ord( str[2] ) % 2 === 0
                   ]
        else
            mode = [ 0 + self.ord( str[2] ) % (3 + 1 - 0), 
                     self.ord( str[2] ) % 2 === 0
                   ]
        end

        padded = self.ord( str[3] ) - 1
        blk_full = blk_random + blk_original

        str = str.slice(4, str.length )
        raise ArgumentError, 'descramble(): Incorrect input or configuration, string couldn\'t be split into the required chunks based on input and configuration.' if str.length % blk_full != 0
        str = self.split( str, blk_full )
         
        if mode[0] === 0
        
            for i in 0...str.length
                str[i] = str[i].slice( blk_random, str[i].length )
            end

        elsif mode[0] === 1
        
            for i in 0...str.length
                str[i] = str[i].slice( 0, str[i].length - blk_random )
            end        
                
        elsif mode[0] === 2
        
            for i in 0...str.length 
                if i % 2 === 0
                    str[i] = str[i].slice(0, str[i].length - blk_random)
                else
                    str[i] = str[i].slice( blk_random, str[i].length ).reverse
                end
            end
        
        elsif mode[0] === 3
            _next = mode[1]

            for i in 0...str.length
                if _next === true
                    _next = self.ord( str[i][blk_full - blk_random] ) % 2 === 0 
                    str[i] = str[i].slice( 0, str[i].length - blk_random )
                else
                    _next = self.ord( str[i][0] ) % 2 === 0
                    str[i] = str[i].slice( blk_random, str[i].length ).reverse
                end
            end
        end
        
        str = str.join

        if padded > 0
        
            if mode[1] === true
                str = str.slice( 0, str.length - padded )
            else
                str = str.slice( padded, str.length ) 
            end
        end

        return str
    end
    
    def random_pad ( str, sep = nil )

        sep ||= @@sep 
        
        return false if !sep.kind_of? String
        return false if (len = str.length) < 1
        return false if !self.chk_str(sep, 1, 1)

        str << sep
        pad_str = ''
        max = len < 500? 700 : 200;
        pad_len = rand(0..max)
        replace = self.ord( sep ) < 128? self.chr( rand(128..255) ) : self.chr( rand(1..127) )

        for i in 0...pad_len do
            pad_str << self.chr( rand(1..255) )
        end

        pad_str = pad_str.gsub( sep , replace )

        return str << pad_str
    end
    
    def random_pad_remove ( str, sep = nil )

        sep ||= @@sep
        
        return false if !self.chk_str(str, 1)
        return false if !self.chk_str(sep, 1, 1)
       
        pos = str.rindex( sep )    
        return false if pos.nil?
        str = str.slice( 0, pos )
        
        return str
    end
    
    def chk_str( input, min_len = nil, max_len = nil )

        raise ArgumentError, 'chk_str(): min_len must be an integer or a nil value.' if !min_len.kind_of? Integer and !min_len.nil?
        raise ArgumentError, 'chk_str(): max_len must be an integer or a nil value.' if !max_len.kind_of? Integer and !max_len.nil?

        if !min_len.nil? && !max_len.nil?
            raise ArgumentError, 'chk_str(): min_len can\'t be larger than max_len.' if min_len > max_len
        end

        if !input.kind_of? String
            return false
        else
            output = true
        end

        if !min_len.nil?
            output = false if input.bytesize < min_len
        end

        if !max_len.nil?
            output = false if input.bytesize > max_len
        end

        return output
    end

    def chk_int ( input, min = nil, max = nil )

        raise ArgumentError, 'chk_int(): min must an integer or a nil value.' if (!min.kind_of? Integer) && (!min.nil?)
        raise ArgumentError, 'chk_int(): max must an integer or a nil value.' if (!max.kind_of? Integer) && (!max.nil?)

        if !min.nil? && !max.nil?
             raise ArgumentError, 'chk_int(): min can\'t be larger than max.' if min > max
        end

        if !input.kind_of? Integer
            return false
        else
            output = true
        end

        if !min.nil?
            output = false if input < min
        end

        if !max.nil?
            output = false if input > max
        end

        return output
    end

    def chk_array ( input, min_index = nil, max_index = nil )

        raise ArgumentError, 'chk_array(): min_index must be an integer or a nil value.' if !min_index.kind_of? Integer and !min_index.nil?
        raise ArgumentError, 'chk_array(): max_index must be an integer or a nil value.' if !max_index.kind_of? Integer and !max_index.nil?

        if !min_index.nil? and !max_index.nil?
            raise ArgumentError, 'chk_array(): min-index can\'t be larger than max_index.' if min_index > max_index
        end

        if input.kind_of? Array
            return false
        else 
            output = true
        end

        if !min_index.nil?
            output = false if input.length < min_index
        end

        if !max_index.nil?
            output = false if input.length > max_index
        end
        
        return output
    end
    
    def ord ( char )
        return false unless char.kind_of? String
        return false if char.length != 1
        return char.unpack('C')[0]
    end
    
    def chr ( int )
        return false unless int.kind_of? Integer
        return int > -1 && int < 256? [int].pack('C') : false
    end
    
    def split ( str, chunk_size )
        raise ArgumentError, 'split(): str must be a string' if !str.kind_of? String
        raise ArgumentError, 'split(): chunk_size must be an integer' if !chunk_size.kind_of? Integer
        raise ArgumentError, 'split(): chunk_size can\'t be less than 1.' if chunk_size < 1
      
        return str.unpack("a#{chunk_size}" * ((str.bytesize / chunk_size) + ((str.bytesize % chunk_size > 0 )? 1 : 0)) )
    end
end
Advertisement
The easiest way to create a website for your business. Create your site at Weebly.com!


Random Article You May Like