Find Jobs
Hire Freelancers

C# Class for OATH/HMAC/SHA1 OTP (one time password)

$100-200 USD

Terminado
Publicado hace más de 15 años

$100-200 USD

Pagado a la entrega
I need a C# class with a single static method that can generate the proper one time password given a secret, a counter, and a length. The signature of the class should be something like this... public class HmacOTP { public static String Generate(String secret, int counter) { String otp; // do work return otp; } } ===== Background ===== This is using the one time password (OTP) standard put out by the OATH consortium ([login to view URL]). This OTP technology is usually seen in hardware security tokens ([login to view URL]). I have a short class in Ruby that does this. ## Deliverables NOTE: this must be in managed code, all C#. Also, there is an HMACSHA1 class in .NET that is probably the best starting point. RFC for this can be found here ([login to view URL]). ===== Ruby equivalent ===== Here is a class in Ruby that does what I need... =begin rdoc Copyright (c) 2007, Vonage Holdings All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Vonage Holdings nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Authors: Michael DeCandia <mdecandia@[login to view URL]> and Stephen Becker <sbecker@[login to view URL]> === HOTP The HOTP object can be used to calculate the HOTP value for any secret and count. The number of digits in the HOTP value is determined by an optional parameter. The default HOTP value is 6 digits long. Creating an HOTP instance h = [login to view URL]() h.secret="12345678901234567890" # 20 byte key h.count=0 # Where to start calculating h.digits=6 # How many digits to return (length of the HOTP value) puts([login to view URL]) # => "755224" h.count=1 # Change the count puts([login to view URL]) # => "287082" Using HOTP as a class method secret = "12345678901234567890" count = 0 puts(HOTP::hotp(secret,count)) # => "755224" =end require 'openssl' require 'logger' #This implements HOTP: An HMAC-Based One-Time Password Algorithm as described in RFC 4226 ([login to view URL]) class HOTP #The secret key in ascii (K) attr_accessor :secret #The count used to start the calculation (C) attr_accessor :count #The length of the HOTP value (Digit) (Defaults to 6) attr_accessor :digits #The default logger to use when reporting an error. (Defaults to STDERR) @@logger = [login to view URL](STDERR) #Creates an HOTP object #* :secret is your secret key #* :count is where to start your calculation #* :digits is the length of the HOTP value # #Creating an HOTP instance # # h = [login to view URL]() # h.secret="12345678901234567890" # 20 byte key # h.count=0 # Where to start calculating # h.digits=6 # How many digits to return (length of the HOTP value) # puts([login to view URL]) # => "755224" # h.count=1 # Change the count # puts([login to view URL]) # => "287082" # # #Using HOTP as a class method # # secret = "12345678901234567890" # count = 0 # puts(HOTP::hotp(secret,count)) # => "755224" # def initialize(secret=nil,count=nil,digits=6) begin @secret = secret @count = count @digits = digits rescue Exception => e @@[login to view URL]{"Unable to initialize HOTP properly. Reason: #{e}"} end end #Returns the HOTP value as a string def update begin return calculate_hotp(@secret, @count, @digits) rescue Exception => e @@[login to view URL]{"Unable to update. Reason #{e}"} end end alias_method :hotp, :update #Returns the HOTP value as a string def calculate_hotp(secret,count,digits=6) return HOTP::hotp(secret,count,digits) end #Set the Logger object. By default this logs to STDERR def self.logger=(logger) @@logger = logger end #Class method that returns the HOTP value as a string def [login to view URL](secret,count,digits=6) begin # The secret is plain text # i.e "1234567891234567890" # The count needs to be in hex so we need to convert it into a padded hex string # i.e. 10 = "\x00\x00\x00\x00\x00\x00\x00\x0a" # The digits are the number of digits to use when calculating the HOTP. (defaults to 6) sha1_hash = OpenSSL::[login to view URL](OpenSSL::Digest::[login to view URL]("SHA1"), secret, string_to_hex_value(count,8)) #the last hex value is the offset offset = sha1_hash[-1].[login to view URL] #get the string in the offset range dbc1 = sha1_hash[(offset*2)...((offset*2)+8)] #31bits dbc2 = [login to view URL] & "7fffffff".hex hotp = dbc2%(10**digits.to_i) hotp = sprintf("%0#{digits}d", hotp) return hotp rescue Exception => e @@[login to view URL]{"Unable to calculate the HOTP value. Reason: #{e}"} end end private #Private class method that converts a string to a padded hex value def self.string_to_hex_value(count,padding=nil,pad_char="0") begin return_string = "" # Change count to an integer then base 16 convert to a string # i.e. 10.to_s(16) = a hex_count = count.to_i.to_s(16) #string # Pad the resulting string with the pad_charater ("0" by default) # i.e. Takes "a" and makes it "000000a" # We multiply the padding by two since we evaluate the hex as two characters # i.e. "a" in hex is "0a" ((padding.to_i*2) - [login to view URL]).times{[login to view URL](0,pad_char)} if padding hex_count = "0"+hex_count if [login to view URL]%2==1 temp_char = "0" [login to view URL](/../).each { |hexs| temp_char[0]= [login to view URL] return_string << temp_char } return return_string rescue Exception => e @@[login to view URL]{"Unable to convert string to hex. Reason #{e}"} end end end
ID del proyecto: 3140262

Información sobre el proyecto

5 propuestas
Proyecto remoto
Activo hace 16 años

¿Buscas ganar dinero?

Beneficios de presentar ofertas en Freelancer

Fija tu plazo y presupuesto
Cobra por tu trabajo
Describe tu propuesta
Es gratis registrarse y presentar ofertas en los trabajos
Adjudicado a:
Avatar del usuario
See private message.
$85 USD en 14 días
4,8 (3 comentarios)
2,2
2,2
5 freelancers están ofertando un promedio de $141 USD por este trabajo
Avatar del usuario
See private message.
$170 USD en 14 días
4,8 (124 comentarios)
5,7
5,7
Avatar del usuario
See private message.
$170 USD en 14 días
4,9 (14 comentarios)
5,0
5,0
Avatar del usuario
See private message.
$127,50 USD en 14 días
4,7 (11 comentarios)
3,6
3,6
Avatar del usuario
See private message.
$153 USD en 14 días
0,0 (0 comentarios)
0,0
0,0

Sobre este cliente

Bandera de UNITED STATES
San Antonio, United States
4,9
4
Miembro desde ago 23, 2007

Verificación del cliente

¡Gracias! Te hemos enviado un enlace para reclamar tu crédito gratuito.
Algo salió mal al enviar tu correo electrónico. Por favor, intenta de nuevo.
Usuarios registrados Total de empleos publicados
Freelancer ® is a registered Trademark of Freelancer Technology Pty Limited (ACN 142 189 759)
Copyright © 2024 Freelancer Technology Pty Limited (ACN 142 189 759)
Cargando visualización previa
Permiso concedido para Geolocalización.
Tu sesión de acceso ha expirado y has sido desconectado. Por favor, inica sesión nuevamente.