Im new to Jruby and I need some help with this code. I know im doing this wrong. I really need help with how to get this right.
What am I doing? Mask user password input in JRuby.
Plan: Use java's System.console to do it.
code:
require "rubygems"
require "java"
include_class 'java.io.PrintStream'
include_class 'java.io.ByteArrayOutputStream'
include_class 'java.lang.System'
include_class 'java.io.Console'
Console console = System.console();
String password = console.readPassword("Enter password: ");
puts password
Please help. Thank you
it needs to be converted from char[] back into a String object, something like this:
require "java"
include_class 'java.lang.System'
include_class 'java.io.Console'
console = System.console();
password = console.readPassword("Enter password: ");
passwordString = java.lang.String.new(password)
printf("%s\n", passwordString )
You need to read the password into a char[], convert it to a java.lang.String, and then convert that into a Ruby String:
require 'java'
include_class 'java.lang.System'
include_class 'java.io.Console'
# Read the password into a char[]
java_char_array = System.console.readPassword("password:")
# Turn that into a java.lang.String
java_string = java.lang.String.new(java_char_array)
# Turn this into a Ruby string and strip off the newline.
password = java_string.to_s.strip
The reason that read_password gives you back a char[] is a bit complicated, but it boils down to a big song and dance about security. You can use Array.fill to nuke the contents of char[] and thus keep the password from ending up sitting around in memory for a long time.
Try this,
console = System.console();
String password = console.readPassword("Enter password: ");
puts password
Related
Before we begin I want to make it clear that I know how bad this question is. It's a terrible situation but I'm being constrained by some very strange specifications.
I know that not only should you not try to write your own wrappers for this kind of stuff, but Microsoft have made it clear this shouldn't even be used. So before you start writing replies saying "Why are you even doing this" please try to understand that I have had these conversations with my superiors already, but the push for new features and lack of time means that despite it being atrocious; nevertheless - here I am.
We have an ASP Net membership database, started some time well before my time at this company and now hosting some 40k users. We have a platform in .Net 3.5 which lets users log in.
My job currently is to write an API in .Net Core 2.1 part of which is to allow for user creation and updating but there in lies the problem - migrating from Membership to Identity is not an option so I've been told to create a wrapper for the stored procedures in the Membership database.
This has been mostly successful with the only issue being; the subject of this question. Creating a user via aspnet_Membership_CreateUser I need to submit the data in such a way that it can be successfully validated in our platform.
I had originally followed this post but found that it's been designed for PasswordFormat 1 - Hashed; I then found that our user base used PasswordFormat 2 - Encrypted and as such the users I was creating would not validate.
The code looked something like this
public bool CreateUser(string userName, string password, string email, string securityQuestion, string securityAnswer, bool isApproved)
{
bool success = false;
//Just so I can attempt to login afterwards
password = "Hello World!";
//Our password and password salt need to be base64 encoded before we can save them to the DB
string salt = Guid.NewGuid().ToString();
string encryptedSalt = salt.Base64Encode();
//Concatenate our salt and password
IEnumerable<byte> saltedpass = salt.GetBytes(Encoding.UTF8).Concat(password.GetBytes(Encoding.UTF8));
//Use SHA1 to hash more - equivilant to the HASHBYTES('SHA1' T-SQL
byte[] sha1HashedPass = PasswordHelper.HashBytes(_validationMethod, saltedpass.ToArray(), _validationKey);
string hashedPass = sha1HashedPass.ToBase64String();
int errorCode = MembershipCreateUser(_applicationName, userName, hashedPass, encryptedSalt, email, securityQuestion, securityAnswer, isApproved);
if (errorCode == 0)
{
success = true;
}
return success;
}
Worth noting that _validationKey is the machine key shared across the applications which use this database, which I'm passing into the SHA1 mechanism.
So, intentionally and woefully bad security practice aside;
Is there a way in C# to generate an encrypted (not hashed) passwords and salts in this way?
Thank you for the comments - thankfully we were able to support Hashed passwords in our platform; the issue was with my code and not ASP Membership.
As mentioned I was taking a post that was originally written in T-SQL and trying to build a C# implementation of it. My implementation of this code was incorrect and as such the passwords and salts I was generating were not able to be validated by ASP Net Membership, this was not obvious in my original post because I had obfuscated the method which was SHA1 hashing my data.
//Using hard coded just for example
string username = "joeborder";
string password = "Hello World!";
string salt = "TastySalt";
Encoding encoder = Encoding.Unicode; //Encoding was also incorrect
//Our password and password salt need to be base64 encoded before we can save them to the DB
string encryptedSalt = salt.Base64Encode();
//Concatenate our salt and password
IEnumerable<byte> saltedpass = salt.GetBytes(encoder).Concat(password.GetBytes(encoder));
//Use SHA1 to hash more - equivilant to the HASHBYTES('SHA1') T-SQL
var SHA1Hasher = new SHA1CryptoServiceProvider(); //Originally I was using HMACSHA1 which was producing a different output
byte[] sha1HashedPass = SHA1Hasher.ComputerHash(saltedpass.ToArray());
string hashedPass = sha1HashedPass.ToBase64String();
/*
EXEC aspnet_Membership_CreateUser
#ApplicationName = "MyApp",
#UserName = username,
#Password = hashedPass,
#PasswordSalt = encryptedSalt,
...Etc
*/
Then in our .Net 3.5 application the following code would work
string username = "joeborder";
string password = "Hello World!";
if (Membership.ValidateUser(username, password))
{
Console.WriteLine("You've gotta be kidding me thats a clutch");
}
I have a simple Logic App that uses a SFTP connector, followed by a condition with an expression that states:
Object Name: File Name
Relationship: starts with
Value: '943'
The expression ends up being:
"#startsWith(triggerOutputs()['headers']['x-ms-file-name'], '''943''')"
But the condition always fails even when the file starts with 943.
When trying to debug this I decided to write the "file name" property to the body of a Service Bus Queue and then read it from a simple Windows app. When getting the body as a string, it always threw an exception. I had to rewrite it to use a stream to read it.
Failed Code:
Dim s as String = message.GetBody(of String)()
Working Code:
Dim stream As Stream = message.GetBody(Of Stream)()
Dim reader As StreamReader = New StreamReader(stream)
Dim s As String = reader.ReadToEnd
Does this mean "file name" is not a string but something else like a byte array? How do I get my condition in my Logic App to work properly?
Try update
"#startsWith(triggerOutputs()['headers']['x-ms-file-name'], '''943''')"
to
"#startsWith(triggerOutputs()['headers']['x-ms-file-name'], '943')"
Looks like basic mode will treat 123 as int, but adding additional quotes when entered '123', so you will need to make the change by switching to advanced mode.
I've been trying to call a Powershell script with multi params from an C# ASP.NET file in the following way.
string exe = #"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Powershell.exe";
string template = #"-File {0} -macList{1} -version {2} -server {3}";
string file = #" E:\TestmanagerFor3.7.ps1";
string maclist = "MAC1,MAC2";
string version = "4.0";
string server = "xxx.xxx.xxx.xx";
string parameters = String.Format(template, file, macList, version, server);
Process.Start(exe, parameters);
(Please note that here I have two inputs for the macList)
But while running, this is taking MAC1,MAC2 as a single param only. Here's the parameter list of Testman.ps1:
Param
(
[Parameter(Mandatory=$True,Position=1)]
[String[]]$macList,
[Parameter(Mandatory=$True,Position=2)]
[String]$version,
[Parameter(Mandatory=$True,Position=3)]
[String]$server
)
Please help me fixing this issue.
Thanks in advance,
/Aravind
Take a look at the answer to this question: Scheduled Task for PowerShell Script with String Array Parameter
It suggests changing using the -Command switch instead of the -File switch, and then use the invocation operator '&'.
I have created a wesite in asp.net and use ms-sql database to save the records. Now want to convert it in node.js application. And want to use same sql database. In asp.net application I have encrypt the password for registered user. Below is code.
public static string CreateHash(string unHashed)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.ASCII.GetBytes(unHashed);
data = x.ComputeHash(data);
return System.Text.Encoding.ASCII.GetString(data);
}
public static bool MatchHash(string HashData, string HashUser)
{
HashUser = CreateHash(HashUser);
if (HashUser == HashData)
return true;
else
return false;
}
Now problem is that how I use same encryption in node.js. So when node application is ready old user can also make login. It only possible if node app also use same encryption that I have use in asp.net.
For node I have created all environment and use mssql module for database communication. Please help me fix that. Thanks!!
First of all MD5 shall no longer be used if you are serious about security.
Based on your comment and code, I fear there is a 'data loss' in the initial ASP.net code.
Let us have a look at CreateHash function again, I've added comments:
public static string CreateHash(string unHashed)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
// Convert unHashed string to bytes using ASCII coding
byte[] data = System.Text.Encoding.ASCII.GetBytes(unHashed);
// Compute MD5 hash from bytes
data = x.ComputeHash(data);
// Decode MD5 resulting bytes as ASCII
return System.Text.Encoding.ASCII.GetString(data);
}
The last line confuses me, it is decoding bytes received from MD5 function as if they were ASCII, but that is incorrect assumption. And the resulting encoded string as you gave in comment contains lots of "?'s".
Next node.js code will do similar except encode the string using hex rather than ascii:
var crypto = require('crypto')
function createHash(data) {
return crypto.createHash('md5').update(data, 'ascii').digest('hex')
}
To emulate "bytes to ascii" you could try .digest('binary') instead of hex. If it does not give what you expect, then you have to make a separate 'conversion' step from hex to ascii. (I am not experienced enough to give you elegant solution to the later one)
I am wondering what is the extent of functionality that add-ons/plugins can provide with Firefox. For example, can we edit the way Firefox reads and writes to its Sqlite database?
I am considering a project where we would encrypt the contents of this database when writing to it, and decrypt from it when reading from it. It would be cool if we could do this through the use of a plugin or add-on. Does anyone know if this is feasible or not?
You can create a new SQLLite DB and write to it via a firefox plugin. See https://developer.mozilla.org/en/storage
I've done this previously for a Firebug plugin that I've created. From your plugin you do something like this:
var file = Components.classes["#mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);
file.append("rttplog.sqlite");
var storageService = Components.classes["#mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
this.mDBConn = storageService.openDatabase(file);
this.mDBConn.executeSimpleSQL("CREATE TEMP TABLE log (id INTEGER, type VARCHAR, message TEXT)");
Inserting:
var statement = this.mDBConn.createStatement("INSERT INTO log VALUES(:id, :type, :message)");
statement.params.id = id;
statement.params.type = type;
statement.params.message = message;
statement.execute();
Selecting:
var statement = this.mDBConn.createStatement("SELECT id FROM log WHERE message LIKE :query ESCAPE '/' ");
var escaped = statement.escapeStringForLIKE(query, "/");
statement.params.query = "%" + escaped + "%";
return statement.executeAsync(callback);
Hope that helps.