how to create encrypted password field [duplicate] - sql-server

This question already has answers here:
how to encrypt the password column
(6 answers)
Closed 3 years ago.
I want to create a table and there is one field that I want to make encrypted but I don't know how to make it. It would be better if the solution is in SQL.

you can try these methods to encrypt and decrypt:
To encrypt:
public string Encrypt(string plainText)
{
if (plainText == null) throw new ArgumentNullException("plainText");
//encrypt data
var data = Encoding.Unicode.GetBytes(plainText);
byte[] encrypted = ProtectedData.Protect(data, null, Scope);
//return as base64 string
return Convert.ToBase64String(encrypted);
}
Decrypt Method:
public string Decrypt(string cipher)
{
if (cipher == null) throw new ArgumentNullException("cipher");
//parse base64 string
byte[] data = Convert.FromBase64String(cipher);
//decrypt data
byte[] decrypted = ProtectedData.Unprotect(data, null, Scope);
return Encoding.Unicode.GetString(decrypted);
}

Related

Check if SSH Private Key is Encrypted

Key pairs generated with ssh-keygen on macOS can have different formats.
The standard PEM ASN.1 object which is readable by macOS' SecKey APIs
A PEM with textual headers
OpenSSH Keys
OpenSSH Encrypted Keys
OpenSSH/BSD uses this non-standardized format here.
Now I only need to be able to check if a private key has a passphrase set or not, so I can prompt the user to enter it, without having to deal with the complexities of different key formats.
Is there a quick way on macOS via Swift or C API, to check if a key has a passphrase set?
The difference between the unencrypted and encrypted private keys is the fact that the key blob is encrypted. You need to decrypt the private key blob data before you can use the private key blob. So once the encrypted private key data is decoded, you can treat it the same as the unencrypted private key data.
A unencrypted private key blob PEM file looks like this:
—–BEGIN PRIVATE KEY—–
{base64 private key blob)
—–END PRIVATE KEY—–
The encrypted RSA private key PEM file looks like this:
—–BEGIN RSA PRIVATE KEY—–
Proc-Type: 4,ENCRYPTED
DEK-Info: {encryption algorithm},{salt}
{base64 encrypted private key blob)
—–END RSA PRIVATE KEY—–
e.g.
—–BEGIN RSA PRIVATE KEY—–
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,AB8E2B5B2D989271273F6730B6F9C687
{base64 encrypted private key blob)
—–END RSA PRIVATE KEY—–
So to decode the private key data you need to:
Parse the DEK-Info encryption algorithm and the salt (good idea to confirm the first line is: "Proc-Type: 4,ENCRYPTED" as well).
Decode the base64 encrypted private key blob.
Generate the encryption algorithm "key" and "IV" based on the salt and the passphrase
Decode the encrypted private key blob.
Once you have done that the decrypted private key blob can be treated just like the unencoded private key blob.
The number of supported encryption algorithm's are rather large, so you may like to support a sub-set of algorithms. e.g. "DES-EDE3-CBC", "AES-xxx-CBC", etc
To generate the IV you need to convert salt string to binary. The salt string is a hex encoded string, so convert each two strings characters into a byte using a hex string character to byte converter.
For the generation of the encryption algorithm key you need the key size (e.g. DES-EDE3-CBC is 192bits, AES-256-CBC is 256bits). Build up the key "bits" with a loop appending MD5 hash results to the key until generate all the key bits required.
The MD5 HASH loop generation will consist of:
First MD5 Hash: MD5 hash of the first 8 bytes of the IV and the Passphrase
All other MD5 Hashes is the MD5 hash of the last MD5 hash result and the first 8 bytes of the IV and the Passphrase
See the openssl source for EVP_BytesToKey method for an example of the key bits generation.
The encrypted private key blob can now be decoded using the selected encryption algorithm using the IV and KEY build above.
There are two ways that I would suggest. Either reading the command line output using readLine() and checking if it asks for a password then do something accordingly.
import Foundation
func runCommand(cmd : String, args : String...) -> (output: [String], error: [String], exitCode: Int32) {
var output : [String] = []
var error : [String] = []
let task = Process()
task.launchPath = cmd
task.arguments = args
let outpipe = Pipe()
task.standardOutput = outpipe
let errpipe = Pipe()
task.standardError = errpipe
task.launch()
let outdata = outpipe.fileHandleForReading.readDataToEndOfFile()
if var string = String(data: outdata, encoding: .utf8) {
string = string.trimmingCharacters(in: .newlines)
output = string.components(separatedBy: "\n")
}
let errdata = errpipe.fileHandleForReading.readDataToEndOfFile()
if var string = String(data: errdata, encoding: .utf8) {
string = string.trimmingCharacters(in: .newlines)
error = string.components(separatedBy: "\n")
}
task.waitUntilExit()
let status = task.terminationStatus
return (output, error, status)
}
//Sample usage
let (output, error, status) = runCommand(cmd: "/usr/local/bin/node", args: "--version")
print("program exited with status \(status)")
if output.count > 0 {
print("program output:")
print(output)
//HERE YOU CAN CHECK IF PASSWORD REQUEST HAS BEEN MADE
}
if error.count > 0 {
print("error output:")
print(error)
}
The example code will return your node version installed if there is one, but you could use it to check if a password prompt has been made by the system for the RSA Key.
The other way could be perhaps using a third-party library like SwiftyRSA or BlueRSA which might help with validation.
I implemented my own OpenSSH check for the 2 most common formats
For one I'm checking the PEM headers for DEK-Info for Linux-style SSH PEMs
For OpenSSH style keys I manually parse the format using the class below
import Foundation
private let opensshMagic = "openssh-key-v1"
public class SSHPrivateKey {
public struct OpenSSHKey {
let cipherName: String
let kdfName: String
let kdfOptions: Data
let numKeys: Int
var isEncrypted: Bool {
return cipherName != "none"
}
}
public let data: Data
public init(data: Data) {
self.data = data
}
public func openSSHKey() -> OpenSSHKey? {
// #define AUTH_MAGIC "openssh-key-v1"
//
// byte[] AUTH_MAGIC
// string ciphername
// string kdfname
// string kdfoptions
// int number of keys N
// string publickey1
// string publickey2
// ...
// string publickeyN
// string encrypted, padded list of private keys
guard let magic = opensshMagic.data(using: .utf8) else {
return nil
}
if data.prefix(magic.count) != magic {
return nil
}
var offset = magic.count + 1
guard let cipherName = data.consumeString(offset: &offset),
let kdfName = data.consumeString(offset: &offset) else {
return nil
}
let kdfOptions = data.consumeBytes(offset: &offset)
let numKeys = data.consumeUInt32(offset: &offset)
return OpenSSHKey(cipherName: cipherName,
kdfName: kdfName,
kdfOptions: kdfOptions,
numKeys: Int(numKeys))
}
}
private extension Data {
func consumeBytes(offset: inout Int) -> Data {
let n = Int(consumeUInt32(offset: &offset))
let b = Data(self[offset..<offset + n])
offset += n
return b
}
func consumeString(offset: inout Int) -> String? {
return consumeBytes(offset: &offset).utf8String
}
func consumeUInt8(offset: inout Int) -> UInt8 {
let v = self[offset] & 0xFF
offset += 1
return v
}
func consumeUInt32(offset: inout Int) -> UInt32 {
var i: UInt32 = 0
i = (i << 8) | UInt32(consumeUInt8(offset: &offset))
i = (i << 8) | UInt32(consumeUInt8(offset: &offset))
i = (i << 8) | UInt32(consumeUInt8(offset: &offset))
i = (i << 8) | UInt32(consumeUInt8(offset: &offset))
return i
}
}

TextEncodings.Base64Url.Decode vs Convert.FromBase64String

I was working on creating a method that would generate a JWT token. Part of the method reads a value from my web.config that services as the "secret" used to generate the hash used to create the signature for the JWT token.
<add key="MySecret" value="j39djak49H893hsk297353jG73gs72HJ3tdM37Vk397" />
Initially I tried using the following to convert the "secret" value to a byte array.
byte[] key = Convert.FromBase64String(ConfigurationManager.AppSettings["MySecret"]);
However, an exception was thrown when this line was reached ...
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
So I looked into the OAuth code and so another method being used to change a base64 string into a byte array
byte[] key = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["MySecret"]);
This method worked without issue. To me it looks like they are doing the same thing. Changing a Base64 text value into an array of bytes. However, I must be missing something. Why does Convert.FromBase64String fail and TextEncodings.Base64Url.Decode work?
I came across the same thing when I migrated our authentication service to .NET Core. I had a look at the source code for the libraries we used in our previous implementation, and the difference is actually in the name itself.
The TextEncodings class has two types of text encoders, Base64TextEncoder and Base64UrlEncoder. The latter one modifies the string slightly so the base64 string can be used in an url.
My understanding is that it is quite common to replace + and / with - and _. As a matter of fact we have been doing the same with our handshake tokens. Additionally the padding character(s) at the end can also be removed. This leaves us with the following implementation (this is from the source code):
public class Base64UrlTextEncoder : ITextEncoder
{
public string Encode(byte[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return Convert.ToBase64String(data).TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
public byte[] Decode(string text)
{
if (text == null)
{
throw new ArgumentNullException("text");
}
return Convert.FromBase64String(Pad(text.Replace('-', '+').Replace('_', '/')));
}
private static string Pad(string text)
{
var padding = 3 - ((text.Length + 3) % 4);
if (padding == 0)
{
return text;
}
return text + new string('=', padding);
}
}

Input Mismatch scanner.next(string pattern) from file

I'm having a problem while using a
Scanner file = new Scanner(filePath);
my file is organised as so
Question x.y
Answer1
Answer2
Answer3
Answer4
Hint: Hint to Question x.y Level z Genere t
I'm quite new to java and in all of this project I've used
.next(string pattern)
to return a string that includes the parrtern and arrives to the end of the line but i continue to get mismatch exceptions.. i don't really get what
https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
defines as token and for this reason i don't know how to handle it..
my code is
public Question getQuestion(String filePath)
{
ArrayList questions = new ArrayList();
Scanner file = new Scanner(filePath);
String questionInFile = "Question";
while(file.hasNextLine())
questions.add(questionInFile+file.next(questionInFile));
Random rg = new Random();
String Q = (String)questions.get(rg.nextInt(10)+1);
file.close();
ArrayList<String> answer=getAnswers(filePath, Q);
String correctAnswer=answer.get(0);
return new Question(Q, answer, correctAnswer);
}
try adding
File filePath = new File(".txt");
before Scanner file

JavaMail and non-ASCII character in filenames

I can send attachments that have non-ascii filenames in JavaMail but I am not able to download them. I am getting java.io.FileNotFoundException specifically for those attachments whose file names contain non-ascii characters.
FYI: I am using something like messageBodyPart.setFileName(MimeUtility.encodeText(filename[i])) to encode the text and MimeUtility.decodeText(bodyPart.getFileName()) to decode the non-ascii file names
Is there a workaround for this?
EDIT
#Bill, here is part of my code that reads attachments. I have also added the properties.setProperty("mail.mime.decodeparameters", "true") and properties.setProperty("mail.mime.decodefilename", "true") properties in my code.
if (message[a].getContent() instanceof MimeMultipart) {
Multipart multipart = (Multipart) message[a].getContent();
for (int i = 0; i < multipart.getCount(); i++) {
bodyPart = multipart.getBodyPart(i);
disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equals(BodyPart.ATTACHMENT) || (disposition.equals(BodyPart.INLINE)))) {
DataHandler handler = bodyPart.getDataHandler();
String path = bodyPart.getFileName();
String[] str = path.split("/");
String fileName = str[str.length - 1];
String filePath = ReadConfigPropertiesFile.getPropertyValue("server.buildpath");
System.out.println(fileName);
File tempDir = new File(filePath + user);
if (!tempDir.exists()) {
tempDir.mkdir();
}
File saveFile = new File(tempDir + "/" + fileName);
int count = 0;
while (saveFile.exists()) {
count++;
saveFile = new File(tempDir + "/" + count + "_" + fileName);
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile));
byte[] buff = new byte[2048];
InputStream is = bodyPart.getInputStream();
int ret = 0;
while ((ret = is.read(buff)) > 0) {
bos.write(buff, 0, ret);
}
bos.close();
is.close();
//System.out.println(bodyPart.getContentType());
}else {
//display body (message) of the attachment;
//System.out.println(bodyPart.getContent().toString());
}
}
}
The above code raises the FileNotFoundException exception at BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile)) line and this is getting raised for the attachments whose file names are non-ascii characters (something like ሰላም.pdf). Every thing else works fine.
This answer taken from comment of #semytech (OP). It was hard to find it there, so I will add it as answer for more visibility. It helped me with hebrew filenames.
MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
You should never need to do the encoding or decoding yourself.
There are two sets of properties you can set to tell JavaMail to do the encoding/decoding for you:
mail.mime.encodefilename/mail.mime.decodefilename
mail.mime.encodeparameters/mail.mime.decodeparameters
See the javadocs for the javax.mail.internet package for details.
The first set uses a non-standard encoding technique, similar to what you're doing yourself. This works fine with some older mailers that use this technique.
The second set uses a MIME standard encoding technique. This version works with most modern mailers.
None of this explains why you're getting FileNotFoundException, but then you didn't provide enough detail to know what you're doing when you get the exception.

How to extract the Signer Info from the Authenticode of a digitally signed PE File encoded using ASN1?

I need to extract the SignerInfo from the Authenticode of a digitally signed PE File in ASN1 structure.
INFO: A PE File contains the authenticode at the offset specified by Security Directory RVA inside Optional Header Data Directories.
I have tried to start after reading the document available at Microsoft Authenticode PE Signature Format but no luck as I am very new to SSL/TSL.
My Question:
Is there a way to parse through the binaries and print the data structure in C String Format?
Is there any way in which I can parse through the given binaries and point to the SignerInfo or SignerName ?
NOTE: I do not want to use any platform dependent APIs as I want the code to be platform-independent.
Thanks in Advance to all Gurus :-)
UPDATE: I found a code in C#. Would anybody help me to find the C equivalent of the same.
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography.X509Certificates;
public class CertInfo
{
public static void Main(String[] args)
{
byte[] certBytes;
X509Certificate x509cert;
while (true)
{
Console.WriteLine("\nEnter File Name: ");
String filename = Console.ReadLine();
if (filename == "") //exit while(true) loop
break;
if (!File.Exists(filename))
{
Console.WriteLine("File \"{0}\" does not exist!\n", filename);
continue;
}
try
{ //try binary DER format first
x509cert = X509Certificate.CreateFromCertFile(filename);
showCertInfo(x509cert);
}
catch (System.Security.Cryptography.CryptographicException cryptder)
{ //not binary DER
StreamReader sr = File.OpenText(filename);
String filestr = sr.ReadToEnd();
sr.Close();
StringBuilder sb = new StringBuilder(filestr);
sb.Replace("-----BEGIN CERTIFICATE-----", "");
sb.Replace("-----END CERTIFICATE-----", "");
//Decode
try
{ //see if the file is a valid Base64 encoded cert
certBytes = Convert.FromBase64String(sb.ToString());
x509cert = new X509Certificate(certBytes);
showCertInfo(x509cert);
}
catch (System.FormatException formexc)
{
Console.WriteLine("Not valid binary DER or Base64 X509 certificate format");
}
catch (System.Security.Cryptography.CryptographicException cryptb64)
{
Console.WriteLine("Not valid binary DER or Base64 X509 certificate format");
}
}
} // end while true
}
private static void showCertInfo(X509Certificate x509cert)
{
Console.WriteLine("Name: " + x509cert.GetName());
Console.WriteLine("Issuer: " + x509cert.GetIssuerName());
Console.WriteLine("Serial Number: " + x509cert.GetSerialNumberString());
Console.WriteLine("Expiration Date: " + x509cert.GetExpirationDateString());
Console.WriteLine("PublicKey: " + x509cert.GetPublicKeyString());
}
}

Resources