simple yet secure encrypt / decrypt asp to asp.net - asp.net

I have a ASP/VB6 web-app that logs in a user. I want to encrypt the users identity field and pass(querystring) it to a asp.net app and then decrypt it to do a db lookup.
I've googled it and found rot13, albeit not secure enough. I've also found some hits on MD5 / RC4, but did not find any good examples of encrypt / decrypt.
Any ideas on how to implement secure encryption/description logic?

I agree with #Brian - don't go doing your own crypto, the crypto is easy until you start doing the key management. Do use SSL/TLS unless you have a very VERY V.E.R.Y. good reason not to do so.

It's generally conceded that you should never decrypt such information, but rather compare encrypted to encrypted.
MD5, for example, can be used in this 'trapdoor' fashion. Encode the information, then store the MD5 hash. When you need to authenticate, encode the new information and compare hashes. The unencrypted information is never exposed or available.
If this doesn't work for your situation, then look into the Windows Crypto API, which offers alternatives that allow full-cycle encrypt / decrypt.

Here is a basic encryption example. You'll want to figure out your own key. I did mine this way to just add one more level of complexity (I hope). As Jim points out you could use this to encrypt a new password, then store the results. After the password is created instead of ever trying to decrypt this value (which is just the reverse), you would encrypt the entered password and compare it against the stored value.
'combine these constants to build the encryption key'
Private Const KEY1 = "abcde"
Private Const KEY2 = "fghij"
Private Const KEY3 = "klmno"
Private Const KEY4 = "pqrst"
Private Const KEY5 = "uvwxy"
Private Function Encrypt(ByVal s As String, ByVal EncryptionType As CAPICOM.CAPICOM_ENCODING_TYPE) As String
Dim oEN As New CAPICOM.EncryptedData
Dim intENCType As CAPICOM.CAPICOM_ENCRYPTION_ALGORITHM
Dim strSecret As String
Dim intTries As Integer
On Error GoTo errEncrypt
intENCType = CAPICOM_ENCRYPTION_ALGORITHM_AES ' try this first and fall back if not supported'
With oEN
startEncryption:
.Algorithm = intENCType
strSecret = KEY2 & KEY5 & KEY4 & KEY1 & KEY3
.SetSecret strSecret
strSecret = ""
.Content = s
' the first encryption type needs to be base64 as the .content property'
' can loose information if I try to manipulate a binary string'
.Content = StrReverse(.Encrypt(CAPICOM_ENCODE_BASE64))
strSecret = KEY1 & KEY4 & KEY3 & KEY2 & KEY5
.SetSecret strSecret
strSecret = ""
Encrypt = .Encrypt(EncryptionType)
End With
Set oEN = Nothing
Exit Function
errEncrypt:
If Err.Number = -2138568448 Then
' if this is the first time the step the encryption back and try again
If intTries < 1 Then
intTries = intTries + 1
intENCType = CAPICOM_ENCRYPTION_ALGORITHM_3DES
Resume startEncryption
End If
End If
Err.Raise Err.Number, Err.Source & ":Encrypt", Err.Description
strSecret = ""
Set oEN = Nothing
End Function

Related

How to encrypt RSA in lua?

I want to convert rsa in Lua using the following parameters. I need to send a 6-digit code as RSA encrypted to perform a payment transaction. I couldn't do this in Lua. Can you share a code sample?
Exponent=AQAB
Modulus=1EYDa43a8My50miTEK2miAzw8Rl/1HqG+XT0LuBdoKtZLdKe35xAOlr0DTk/Bp6...
I don't want to share the full public key for security reasons.
The code sample I developed is as follows.
prm_inData = "123456";
function Encryption(prm_inData)
local outData1 = ""
if(prm_inData ~= nil) then
local IVVee = ""
local len = ""
local len2 = ""
IVVee = AQAB;
len = string.len(prm_inData)
rsa = vpos.crypt.RSA()
if(rsa ~= nil) then
enc= rsa:getPublicKey("1EYDa43a8My50miTEK2miAzw...");
outData1 = rsa:encrypt(prm_inData, IVVee)
end
len2 = string.len(outData1)
return outData1
end
end
The code sample I developed is as follows. When I encrypt it returns 1281. I think I did the operation wrong. Where am I doing wrong? I would appreciate your help.

Python AES Decryption initialization vector & key value- size issue

I am writing Python Decryption logic to decrypt the message (client-side it is encrypted using Java).
Python code:
def decrypt(self, text):
decode = base64.b64decode(text)
cryptor = AES.new(InKey, MODE_CBC, InIV)
plain_text = cryptor.decrypt(decode)
return unpad(plain_text)
I have received below key & IV values (sample values) from the client team:
InKey =
"6asd6587daIs8g2qvi3rJbM9sdasd6cb2kdYC0TOy5zEgTo+8LrQn0UJZAmJCtmX......"(it
is length of 684 chars) InIV =
"7as76cascsagoKtID7z1nUakJqzj+Dwl9cL9Q2/zBFbs0Sg3Kw6US8yvvzbkyg2bnjGHWofIWrhMQ/Bcde...."
(it is length of 684 chars)
Question: While running the above python code, getting the below error. How to convert the above IV value into 16bytes in size and also key-value length?
ValueError: Incorrect IV length (it must be 16 bytes long)
existing Decryption Java Client follows Hybrid pattern(first using RSA private key to pull two params(IV & Key)...and then AES cipher to decrypt actual message):
Pseudo code:
................................
//Step-1) Generate RSA-PrivateKey
................................
RSAPrivateKey serverPrivateKey = KeyUtils.getPrivateKey("lib", PrivKey);
/* here PrivKey refers to .der certificate
and FYI- KeyUtils actually refers to a class, that generate RSA PrivateKey with below code:
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec ks = new PKCS8EncodedKeySpec(privKeyBytes);
return (RSAPrivateKey)keyFactory.generatePrivate(ks);
*/
................................
//Step-2) use RSA-PrivateKey to decrypt the message
................................
MessageEncryption encryptor = new MessageEncryption(serverPrivateKey);
/* initializes Cipher(RSA instance) with passed RSA PrivateKey
this.m_asymmetricalKey = serverPrivateKey;
this.m_asymmetricalCipher = Cipher.getInstance(this.m_asymmetricalKey.getAlgorithm());
*/
encryptor.decryptMessage(JSONresponseBody); // invokes below mentioned method
...............
decryptMessage(JSONObject jsonMessage)
{
.............................
IvParameterSpec initializationVector = new IvParameterSpec(this.m_asymmetricalCipher.doFinal(StringCodec.decodeBase64(jsonMessage.getString("iv").getBytes())));
this.m_asymmetricalCipher.init(2, this.m_asymmetricalKey);
Key secretKey = new SecretKeySpec(this.m_asymmetricalCipher.doFinal(StringCodec.decodeBase64(jsonMessage.getString("key").getBytes())), "AES");
Cipher symmetricalCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
symmetricalCipher.init(2, secretKey, initializationVector);
return new String(symmetricalCipher.doFinal(StringCodec.decodeBase64(jsonMessage.getString("message").getBytes())));
.............................
}
..............
So at Python how to get right key-size & IV, is there way to implement similar hybrid pattern at java or does it any other approach to deal with at python ?
Thanks.
Your Java-side code does the following things:
Read the PKCS8-encoded RSA key
Decode the base64-encoded IV
Decrypt the IV using the private key (a side-note: encrypting IV makes very little sense to me)
Decode the base64-encoded AES key
Decrypt the AES key using the private key
Decode the base64-encoded cyphertext
Decrypt the ciphertext using the obtained IV and AES key
You need to re-implement each of the above steps in Python. Some are trivial, like base64-decoding. The others depend on the cryptography libraries you're using.

How to encrypt a string and decrypt this encrypted string in other device in flutter?

I found encrypt package for flutter to encrypt and decrypt a message, I succeded to encrypt and decrypt but don't succeded to use this in a cas of separated device like illustrated.
Here is an example, where I compose a plaintext with a static string and a random number, it permit to change the generated key and when I decrypt, found the static string with regex match
var number = new Random();
var random= number.nextInt(100);
final plainText = 'static_name$random';
final key = Key.fromLength(16);
final iv = IV.fromLength(8);
final encrypter = Encrypter(AES(key));
final encrypted = encrypter.encrypt(plainText, iv: iv);
final decrypted = encrypter.decrypt(encrypted, iv: iv);
print(encrypted.base64);//my plaintext is encrypted fesesgesgneslg465esg6es4g
print(decrypted); //my random plaintext is decrypted static_name$rnd
//my regex match function
Currently I don't find how to enter my encrypted key ( fesesgesgneslg465esg6es4g) I serach to do something like that
//---------on press I generate a random key that I encrypt----
var rng = new Random();
var rnd= rng.nextInt(100); //choisir le nombre max de contenu de la catégorie
final plainText = 'static_name$rnd';
final key = Key.fromLength(16);
final iv = IV.fromLength(8);
final encrypter = Encrypter(AES(key));
final encrypted = encrypter.encrypt(plainText, iv: iv);
//output : 68e4sg68es4ges68g4
//---------the user enter the key(68e4sg68es4ges68g4) on a second device ----
encrypted=68e4sg68es4ges68g4;
final key = Key.fromLength(16);
final iv = IV.fromLength(8);
final encrypter = Encrypter(AES(key));
final decrypted = encrypter.decrypt(encrypted, iv: iv);
print(decrypted);
I can't found how to decrypt my key ( 68e4sg68es4ges68g4)
In few word I succeded to encrypt and decrypt automatically an input but don't succeded to manually add the generated key to the decrypt function.
There's a serious problem with how you are trying to use the encrypt package. By using Key.forLength() you are basically using a key of 0000000....000. The same for IV. That's not a very secure key!
When using a crypto system between two different machines you need to find some way to share the key between them - the so-called "shared secret". You might generate this from a "passphrase" using, for example, PKKDF2. Or you could just compile a random byte string into the code, but expect that an attacker could reverse-engineer your code.
Using AES, you should not use the same IV twice with the same key, which is why cryptosystems typically generate a key and an initial IV uniquely during the key exchange, and then use something (like a message sequence number) to change the IV for each message that's encrypted with that one key.
For test purposes, like yours, you might want to generate a fixed 16 bit key and fixed 16 bit IV using a random number generator like this. Then use the .fromBase64() constructors.
var key = Key.fromBase64('yE9tgqNxWcYDTSPNM+EGQw=='); // obviously, insert your own value!
var iv = IV.fromBase64('8PzGKSMLuqSm0MVbviaWHA==');
Use the same values for key and IV in the encrypting and decrypting app.
You can use this method:
String encrypted = "68e4sg68es4ges68g4";
final decrypted = encrypter.decrypt(encrypt.Encrypted.fromBase64(encrypted),iv:iv);

How to generate MD5 using VBScript in classic ASP?

I need to generate an MD5 in my application.
I've tried google but only find PHP code for MD5. I need to connect to a client system that validates using MD5 hash but their code is in PHP, mine is in Classic ASP using VBScript.
My server is .Net supported so I cannot use the PHP script. Is there any such MD5 code for VBScript in Classic ASP?
Update 2017-02-21 - Now with added HMACSHA256 for JWTs
Update 2016-07-05 - Now with added SHA1 and SHA256
Right, for all of you who have been struggling with this (like myself) and want to know, it is possible!
The following code is split up into several functions so that you can either MD5/sha1/sha256 a string, or a file.
I borrowed the functions GetBytes and BytesToBase64 from another stackexchange, and the code within stringToUTFBytes is based on another stackexchange.
function md5hashBytes(aBytes)
Dim MD5
set MD5 = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")
MD5.Initialize()
'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
md5hashBytes = MD5.ComputeHash_2( (aBytes) )
end function
function sha1hashBytes(aBytes)
Dim sha1
set sha1 = CreateObject("System.Security.Cryptography.SHA1Managed")
sha1.Initialize()
'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
sha1hashBytes = sha1.ComputeHash_2( (aBytes) )
end function
function sha256hashBytes(aBytes)
Dim sha256
set sha256 = CreateObject("System.Security.Cryptography.SHA256Managed")
sha256.Initialize()
'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
sha256hashBytes = sha256.ComputeHash_2( (aBytes) )
end function
function sha256HMACBytes(aBytes, aKey)
Dim sha256
set sha256 = CreateObject("System.Security.Cryptography.HMACSHA256")
sha256.Initialize()
sha256.key=aKey
'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
sha256HMACBytes = sha256.ComputeHash_2( (aBytes) )
end function
function stringToUTFBytes(aString)
Dim UTF8
Set UTF8 = CreateObject("System.Text.UTF8Encoding")
stringToUTFBytes = UTF8.GetBytes_4(aString)
end function
function bytesToHex(aBytes)
dim hexStr, x
for x=1 to lenb(aBytes)
hexStr= hex(ascb(midb( (aBytes),x,1)))
if len(hexStr)=1 then hexStr="0" & hexStr
bytesToHex=bytesToHex & hexStr
next
end function
Function BytesToBase64(varBytes)
With CreateObject("MSXML2.DomDocument").CreateElement("b64")
.dataType = "bin.base64"
.nodeTypedValue = varBytes
BytesToBase64 = .Text
End With
End Function
'Special version that produces the URLEncoded variant of Base64 used in JWTs.
Function BytesToBase64UrlEncode(varBytes)
With CreateObject("MSXML2.DomDocument").CreateElement("b64")
.dataType = "bin.base64"
.nodeTypedValue = varBytes
BytesToBase64UrlEncode = replace(replace(replace(replace(replace(.Text,chr(13),""),chr(10),""),"+", "-"),"/", "_"),"=", "")
End With
End Function
Function GetBytes(sPath)
With CreateObject("Adodb.Stream")
.Type = 1 ' adTypeBinary
.Open
.LoadFromFile sPath
.Position = 0
GetBytes = .Read
.Close
End With
End Function
These can be used as follows:
BytesToBase64(md5hashBytes(stringToUTFBytes("Hello World")))
Produces: sQqNsWTgdUEFt6mb5y4/5Q==
bytesToHex(md5hashBytes(stringToUTFBytes("Hello World")))
Produces: B10A8DB164E0754105B7A99BE72E3FE5
For SHA1:
bytesToHex(sha1hashBytes(stringToUTFBytes("Hello World")))
Produces: 0A4D55A8D778E5022FAB701977C5D840BBC486D0
For SHA256:
bytesToHex(sha256hashBytes(stringToUTFBytes("Hello World")))
Produces: A591A6D40BF420404A011733CFB7B190D62C65BF0BCDA32B57B277D9AD9F146E
To get the MD5 of a file (useful for Amazon S3 MD5 checking):
BytesToBase64(md5hashBytes(GetBytes(sPath)))
Where sPath is the path to the local file.
And finally, to create a JWT:
'define the JWT header, needs to be converted to UTF bytes:
aHead=stringToUTFBytes("{""alg"":""HS256"",""typ"":""JWT""}")
'define the JWT payload, again needs to be converted to UTF Bytes.
aPayload=stringToUTFBytes("{""sub"":""1234567890"",""name"":""John Doe"",""admin"":true}")
'Your shared key.
theKey="mySuperSecret"
aSigSource=stringToUTFBytes(BytesToBase64UrlEncode(aHead) & "." & BytesToBase64UrlEncode(aPayload))
'The full JWT correctly Base 64 URL encoded.
aJWT=BytesToBase64UrlEncode(aHead) & "." & BytesToBase64UrlEncode(aPayload) & "." & BytesToBase64UrlEncode(sha256HMACBytes(aSigSource,stringToUTFBytes(theKey)))
Which will produce the following valid JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.7ofvtkn0z_pTl6WcqRTxw-4eSE3NqcEq9_3ax0YcuIQ
Here is a readable and downloadable version of MD5 as VBS script:
https://github.com/Wikinaut/md5.vbs
It's the code from http://chayoung.tistory.com/entry/VBScript-MD5 (thank you for this unique piece of code).
Thanks for all the links provided above, they were useful but this one I found really did the job if anybody ever needs it.
VBScript-MD5
I have no idea if this code even works, since I have no way of testing it. However, it seems to be what you are asking for.
http://www.bullzip.com/md5/vb/md5-vb-class.htm
Here is an interesting article by Jeff Attwood on hashes. He has some important things to say about MD5:
http://www.codinghorror.com/blog/2012/04/speed-hashing.html
First of all, thank you SgtWilko! :)
Based on your collected information, I've done one function for all (not for base64/Files).
Your code was very useful for me, but I was searching for a more PHP alike (simple) Function to deal with plain text and with a more explicit code.
Edited:
Based on the issue How to hash a UTF-8 string in Classic ASP, I come up with the ADODB.Stream solution. You can now use non-English characters.
Edited:
Parameter PlainText was changed to Target.
You can now use the HMAC versions.
Just use the Target parameter as an array.
Target(0) = PlainText
Target(1) = SharedKey
Thank you again SgtWilko ;)
Announcing the first SHA1 collision (Google Security Blog) February 23, 2017.
With this function you can hash the plain text into:
MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512, HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384 and HMACSHA512
If you need more you can find it in: System.Security.Cryptography Namespace
Function Hash(HashType, Target)
On Error Resume Next
Dim PlainText
If IsArray(Target) = True Then PlainText = Target(0) Else PlainText = Target End If
With CreateObject("ADODB.Stream")
.Open
.CharSet = "Windows-1252"
.WriteText PlainText
.Position = 0
.CharSet = "UTF-8"
PlainText = .ReadText
.Close
End With
Set UTF8Encoding = CreateObject("System.Text.UTF8Encoding")
Dim PlainTextToBytes, BytesToHashedBytes, HashedBytesToHex
PlainTextToBytes = UTF8Encoding.GetBytes_4(PlainText)
Select Case HashType
Case "md5": Set Cryptography = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider") '< 64 (collisions found)
Case "ripemd160": Set Cryptography = CreateObject("System.Security.Cryptography.RIPEMD160Managed")
Case "sha1": Set Cryptography = CreateObject("System.Security.Cryptography.SHA1Managed") '< 80 (collision found)
Case "sha256": Set Cryptography = CreateObject("System.Security.Cryptography.SHA256Managed")
Case "sha384": Set Cryptography = CreateObject("System.Security.Cryptography.SHA384Managed")
Case "sha512": Set Cryptography = CreateObject("System.Security.Cryptography.SHA512Managed")
Case "md5HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACMD5")
Case "ripemd160HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACRIPEMD160")
Case "sha1HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA1")
Case "sha256HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA256")
Case "sha384HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA384")
Case "sha512HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA512")
End Select
Cryptography.Initialize()
If IsArray(Target) = True Then Cryptography.Key = UTF8Encoding.GetBytes_4(Target(1))
BytesToHashedBytes = Cryptography.ComputeHash_2((PlainTextToBytes))
For x = 1 To LenB(BytesToHashedBytes)
HashedBytesToHex = HashedBytesToHex & Right("0" & Hex(AscB(MidB(BytesToHashedBytes, x, 1))), 2)
Next
If Err.Number <> 0 Then Response.Write(Err.Description) Else Hash = LCase(HashedBytesToHex)
On Error GoTo 0
End Function
These can be used as follows:
Hash("sha512", "Hello World")
Produces:
2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b
Hash("sha256", "Hello World")
Produces:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
Hash("md5", "muñeca")
Produces:
ea07bec1f37f4b56ebe368355d1c058f
Hash("sha512HMAC", Array("Hello World", "Shared Key"))
Produces:
28e72824c48da5a5f14b59246905d2839e7c50e271fc078b1c0a75c89b6a3998746bd8b2dc1764b19d312702cf5e15b38ce799156af28b98ce08b85e4df65b32
There is Javascript code that produces an MD5 checksum. One of them, derived from the Google closure library, is available here.
It's pretty easy to produce a Windows Script Component from the Javascript, then call that component from any COM-enabled language, including VB.
Here's a working example.

Reimplement ASP.NET Membership and User Password Hashing in Ruby

I have a large database of users (~200,000) that I'm transferring from a ASP.NET application to a Ruby on Rails application. I don't really want to ask every user to reset their password and so I'm trying to re-implement the C# password hashing function in Ruby.
The old function is this:
public string EncodePassword(string pass, string saltBase64)
{
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] src = Convert.FromBase64String(saltBase64);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
An example hashed password and salt is (and the password used was "password"):
Hashed password: "weEWx4rhyPtd3kec7usysxf7kpk="
Salt: "1ptFxHq7ALe7yXIQDdzQ9Q=="
Password: "password"
Now with the following Ruby code:
require "base64"
require "digest/sha1"
password = "password"
salt = "1ptFxHq7ALe7yXIQDdzQ9Q=="
concat = salt+password
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1)
puts encoded
I'm not getting the correct password hash (I'm getting "+BsdIOBN/Vh2U7qWG4e+O13h3iQ=" instead of "weEWx4rhyPtd3kec7usysxf7kpk="). Can anyone see what the problem might be?
Many thanks
Arfon
Just a quick update, a colleague of mine has solved this:
require "base64"
require "digest"
require "jcode"
def encode_password(password, salt)
bytes = ""
password.each_char { |c| bytes += c + "\x00" }
salty = Base64.decode64(salt)
concat = salty+bytes
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1).strip()
puts encoded
end
I have been tasked with migrating an existing .NET app to Ruby on Rails. I am using the code below to mimic the .NET password hashing. I am very new to Ruby, and don't know .NET at all. The code may not be as clean as it could, but it's a start.
To test, save this as a Ruby script and run with:
ruby script plain_text_password salt_in_base64
e.g.
ruby dotNetHash.rb password123 LU7hUk4MXAvlq6DksvP9SQ==
require "base64"
require "digest"
# Encode password as double-width characters
password_as_text = ARGV.first
double_width_password = []
double_width_password = password_as_text.encode("UTF-16LE").bytes.to_a
# Unencode the salt
salt = Base64.decode64(ARGV[1])
# Concatenate salt+pass
salt_pass_array = []
salt_pass_array = salt.bytes.to_a + double_width_password
# Repack array as string and hash it. Then encode.
salt_pass_str = salt_pass_array.pack('C*')
sha1_saltpass = Digest::SHA1.digest(salt_pass_str)
enc_sha1_saltpass = Base64.encode64(sha1_saltpass).strip()
puts "Encoded SHA1 saltpass is " + enc_sha1_saltpass
You are pretty close. Unfortunately Ruby has no built-in unicode support at the moment, and your hashing function relies on it. There are workarounds. Look around the site on how to do unicode in Ruby.
BTW, I think you forgot to base64 decode the salt, it looks like the ASP.net function does that.
You need to unencode the salt to convert it back to it's byte representation and then concatenate that with the password to get the hashed password value. You're using the encoding salt string directly (which is a different salt) and thus it is hashing to something different.
require "base64"
require "digest/sha1"
password = "password"
salt = Base64.decode64("1ptFxHq7ALe7yXIQDdzQ9Q==")
concat = salt+password
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1)
puts encoded

Resources