MACTripleDES in PHP - c#

I am trying to get a MAC TripleDES equivalent of the C# MACTripleDES class.
I have tried following mcrypt(), but that is just encoding in TripleDES. I need to get an equivalent MACTripleDES string as the one that is generated in C# to authenticate a message.
I have also looked at PHP's hash_hmac() function but it does not give the option of generating a MAC with TripleDES

I'm not sure since Microsoft didn't bother to say what standard their class conforms to, but I suspect that this NIST document is what the Microsoft class is computing, only using triple DES in place of DES.
I guess you will have to write your own method using the primitives in mcrypt.
EDIT 1:
Inspired by the bounty, I have these two examples showing equivalent result in PHP and C#.
First, C#:
using System;
using System.Text;
using System.Security.Cryptography;
namespace TDESMacExample
{
class MainClass
{
public static void Main (string[] args)
{
var keyString = "012345678901234567890123";
var keyBytes = Encoding.ASCII.GetBytes(keyString);
var mac = new MACTripleDES(keyBytes);
var data = "please authenticate me example number one oh one point seven niner";
Console.WriteLine(data.Length);
var macResult = mac.ComputeHash(Encoding.ASCII.GetBytes(data));
Console.WriteLine(BitConverter.ToString(macResult));
// B1-29-14-74-EA-E2-74-2D
}
}
}
Next, PHP:
<?php
$data = 'please authenticate me example number one oh one point seven niner';
$key = '012345678901234567890123'; // Key must be 24 bytes long
$iv = '\x00\x00\x00\x00\x00\x00\x00\x00'; // All zero IV is required
$cipher = mcrypt_cbc(MCRYPT_3DES, $key, $data, MCRYPT_ENCRYPT, $iv);
$mac_result = substr($cipher, -8); // Last 8 bytes of the cipher are the MAC
echo "mac result : " . bin2hex($mac_result);
echo "<br>";
?>

The MAC is simply the last eight bytes of the CBC encrypted data. If the key, IV, and the padding method matches, you should be able to just use those bytes.
For more details about MAC definition, see Appendix F of FIPS-81, DES Modes of Operation.

Related

RSA decryption in .NET 6 - Incorrect parameter

I am working with a friend to decode an RSA-encrypted message. We have a sample working in Go lang but need to do the same in .NET 6+.
package main
import (
"crypto/rand"
cryptorsa "crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"log"
)
type RSA struct {
publicKey *cryptorsa.PublicKey
privateKey *cryptorsa.PrivateKey
}
func NewRSA() (*cryptorsa.PrivateKey, error) {
const pubPEM = `-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----`
key, err := ParsePrivateKey([]byte(pubPEM))
if err != nil {
return nil, err
}
return key, nil
}
func ParsePrivateKey(privateKeyPEM []byte) (*cryptorsa.PrivateKey, error) {
block, _ := pem.Decode(privateKeyPEM)
if block == nil {
return nil, errors.New("decoding private key failed")
}
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, errors.New("parsing private key failed")
}
return privateKey, nil
}
func main() {
rsa, err := NewRSA()
if err != nil {
log.Fatal(err)
}
const encryptedMessage = `
-----BEGIN CVV2 MESSAGE-----
khA8wKKZEvf5uZKacdhhkQIS8u30RaoaASMEkOXCB+BcWx5lAE3KpKNDpppA01f8
Lr84opHTBdj24BUW3zAUbulX4dwX+COipbvOAgT06ndwGe2j2vTj5QP7t4YE/cag
Wnj1jxpN+0XdCW9lFZmmfMry1YanIbMabDyGMuSeF3QkqQKZID9VKX0F5HxG7hsF
GhBoJJ7s8qCoVH41kfJD/xImfHgzPcLrXg56vg+AHgHo/So4dUJUuClcsayclsTP
mRqkQCOqHa2rrB7K15h8B4gVGEQUT4UdAR7dYjoj7tOCYQeT0n27pUAQ/+YK1fGa
rqnHDNgO8CH8LPo3C58uhJ0gR3HmwfY613yg28/iSw1v+UWQiFaxSPJ5DI+2cRji
ZPoWjCj/346r/8mV2tDZCGKKPUXAXIUyYrjGEx/t+jJirX69aoaLC17HBxLGvcUK
cFh/1nXGEbemaOfqWni+vF6qkeeWnDvaYJAcxuivhM/r49aTDYxQ3Pi8o1xWH6Gk
S+8wwKqhUlgD8mF0OWWwMAmb7OBd4e6nYwEIjUcEt6MiOaltpzxMY0biuIUY31WNlnO+M5yh3cZT76fPDzgkSlmVFDVehxK+Tg+N6bk23VYNcKJ8QVpOPAF3zZyu30IT emtx0w+9EqM1KX1sTRgkqIMGeajbfSHFGc07WZobkXk=
-----END CVV2 MESSAGE----- `
block, _ := pem.Decode([]byte(encryptedMessage))
fmt.Println("this is block:", block)
decryptedMessage, err := cryptorsa.DecryptOAEP(sha256.New(), rand.Reader, rsa, block.Bytes, []byte("CVV2"))
if err != nil {
log.Fatal(err)
}
log.Println(fmt.Sprintf("Decrypted number: %s", decryptedMessage))
}
We've tried following for .NET 6 and .NET 7 but it's not working:
using EncryptDecryptRSA;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.OpenSsl;
using System.Security.Cryptography;
using System.Text;
namespace ConsoleTester
{
class Program
{
static void Main(string[] args)
{
string cyphertext = #"khA8wKKZEvf5uZKacdhhkQIS8u30RaoaASMEkOXCB+BcWx5lAE3KpKNDpppA01f8
Lr84opHTBdj24BUW3zAUbulX4dwX+COipbvOAgT06ndwGe2j2vTj5QP7t4YE/cag
Wnj1jxpN+0XdCW9lFZmmfMry1YanIbMabDyGMuSeF3QkqQKZID9VKX0F5HxG7hsF
GhBoJJ7s8qCoVH41kfJD/xImfHgzPcLrXg56vg+AHgHo/So4dUJUuClcsayclsTP
mRqkQCOqHa2rrB7K15h8B4gVGEQUT4UdAR7dYjoj7tOCYQeT0n27pUAQ/+YK1fGa
rqnHDNgO8CH8LPo3C58uhJ0gR3HmwfY613yg28/iSw1v+UWQiFaxSPJ5DI+2cRji
ZPoWjCj/346r/8mV2tDZCGKKPUXAXIUyYrjGEx/t+jJirX69aoaLC17HBxLGvcUK
cFh/1nXGEbemaOfqWni+vF6qkeeWnDvaYJAcxuivhM/r49aTDYxQ3Pi8o1xWH6Gk
S+8wwKqhUlgD8mF0OWWwMAmb7OBd4e6nYwEIjUcEt6MiOaltpzxMY0biuIUY31WNlnO+M5yh3cZT76fPDzgkSlmVFDVehxK+Tg+N6bk23VYNcKJ8QVpOPAF3zZyu30ITemtx0w+9EqM1KX1sTRgkqIMGeajbfSHFGc07WZobkXk=";
string privateKey = #"
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";
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
byte[] b = Encoding.UTF8.GetBytes(cyphertext);
byte[] byteData = Convert.FromBase64String(cyphertext);
Decryption(byteData, privateKey, true);
}
static public void Decryption(byte[] Data, string key, bool DoOAEPPadding)
{
try
{
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
RSA.ImportFromPem(key);
// tried with both false and true
// also provided OEAP padding but no luck
var decryptedData = RSA.Decrypt(Data, false);
}
}
catch (CryptographicException e)
{
Console.WriteLine(e.ToString());
}
}
}
}
With RSA.Decrypt(Data, false) we get:
Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The parameter is incorrect.'
With RSA.Decrypt(Data, true), we get:
System.Security.Cryptography.CryptographicException: 'Cryptography_OAEPDecoding'
Went through a lot of other questions, but didn't work for us.
OAEP has several parameters that must be specified if they differ from the default values of the library used: the content digest, the MGF1 digest and a label. The default values from RFC8017 are SHA-1 for both digests and an empty label (these do not necessarily have to correspond to those of the library used).
Usually, the label is left empty. This is so common that some libraries do not even provide the option to use a different value, as in the case of the native .NET methods, which uses fixed an empty label. Since a different label was applied during encryption, namely CVV2, decryption with the native .NET methods is not possible. Instead, C#/BouncyCastle must be used:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.OpenSsl;
...
byte[] ciphertext = Convert.FromBase64String(ciphertextB64);
PemReader pemReader = new PemReader(new StringReader(privatePkcs1PEM));
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
Sha256Digest sha256 = new Sha256Digest();
OaepEncoding oaepEncoding = new OaepEncoding(new RsaEngine(), sha256, sha256, Encoding.UTF8.GetBytes("CVV2"));
oaepEncoding.Init(false, keyPair.Private);
byte[] plaintext = oaepEncoding.ProcessBlock(ciphertext, 0, ciphertext.Length);
Console.WriteLine(Encoding.UTF8.GetString(plaintext)); // 447
This returns 447 as plain text.
Note that in the above example privatePkcs1PEM must be a PEM encoded private RSA key in PKCS#1 format. privateKey used in your code is missing header and footer (-----BEGIN/END RSA PRIVATE KEY-----), so this is not a valid PEM key (and therefore ImportFromPem() should fail).
If an empty label is applied during encryption, the native .NET methods can be used for decryption: RSA.Decrypt(Byte[], RSAEncryptionPadding) with RSAEncryptionPadding.OaepSHA256. This applies SHA-256 for both digests and an empty label.

c# reading Hebrew text from console

I'm using windows 10 (maybe this is the problem:-) )
I have a simple code that reads text in Hebrew from console them print it's HEX\DEC value
but he give me 00 all the time
on the console window I can see the Hebrew letters
any reason why?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Timers;
using System.IO;
namespace HebTest
{
class Program
{
static public void Main(string[] args)
{
Console.WriteLine("Write your message here - ");
string StringMessage = Console.ReadLine();
Console.WriteLine("print string - " + StringMessage);
///message in HEX
byte [] ByteMessage = Encoding.Default.GetBytes(StringMessage);
string HexMessage = BitConverter.ToString(ByteMessage);
Console.WriteLine("MSG in HEX - " + HexMessage);
Console.Write(
Encoding.Default.GetString(ByteMessage)
);
Console.WriteLine();
foreach (byte p in ByteMessage)
{
Console.Write((char)p + " - " + p );
Console.WriteLine("");
}
}
for example I enter this text
"test אבגד"
and this is what I got :
Write your message here -
test אבגד ---> this I wrote on the console
print string - test
MSG in HEX - 74-65-73-74-20-00-00-00-00
test
t - 116
e - 101
s - 115
t - 116
- 32
- 0
- 0
- 0
- 0
what am I missing?
Thanks ,
You're using Encoding.Default to convert the string into binary. That's almost always a bad idea - it means the same code may work on some machines and not on others. It's pretty much only useful when you want to read/write a text file on that machine, and you're sure that the system default encoding is the right one to use for any machine that runs it. That's rare.
In particular, you're trying to talk to an external device - which means you need to use the encoding it expects. You should find that out, and use the appropriate encoding. For example, if the device expects UTF-8, use:
// Local variable names changed to be more idiomatic C#
string text = Console.ReadLine();
byte[] bytes = Encoding.UTF8.GetBytes(text);
As you've now indicated that the device expects Windows-1255, that's code page 1255, so you get the encoding like this:
Encoding.GetEncoding(1255)
For clarify, I'd probably use a separate variable for that:
string text = Console.ReadLine();
Encoding encoding = Encoding.GetEncoding(1255);
byte[] bytes = encoding.GetBytes(text);
Found the problem (after #Daisy Shipton let me think )
the code is OK
need to go to
control Panel - region - administrative - system locale -
REMOVE V on Beta : use Unicode UTF-8 for worldwide language support
hope it will help someone someday

Get Sha256 public key from certificate

Currently, am working on client server application(Chat) am implementing security for server and clients, few of the client is written in java SMACK library, they are using TLS Pining for JAVA it needs sha2 hash [https://github.com/Flowdalic/java-pinning][1]
Server is implemented using C#, I have certificate on server side how can I get the sha2 public key with below format from the certificate, below is my code.
cer =new X509Certificate2(ConfigurationManager.AppSettings["CertificateName"],"123456");
string hellow= cer.GetCertHashString(); //it will return sha1 hash
what I need is the below format and sha2-256 key from the certificate
SHA2-256 key
83:F9:17:1E:06:A3:13:11:88:89:F7:D7:93:02:BD:1B:7A:20:42:EE:0C:FD:02:9A:BF:8D:D0:6F:FA:6C:D9:D3
I have found the solution for my question, let me share.
If you want to get certificate's SHA256 thumbprint, you have to do some manual work. Built-in Thumbprint property is SHA1 only.
Yo have to use a SHA256 class and compute hash over certificate's content:
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace MyNamespace {
class MyClass {
public static String GetSha2Thumbprint(X509Certificate2 cert) {
Byte[] hashBytes;
using (var hasher = new SHA256Managed()) {
hashBytes = hasher.ComputeHash(cert.RawData);
}
return BitConverter.ToString(hashBytes).Replace("-", ":");
}
}
}

C# not connecting to R using RDotNet

I am trying to interface C# to R using RDotNet.
The following code is wants R to calculate the sum of two numbers and C# to get the result back and display it in the command window.
using System;
using RDotNet;
namespace rcon
{
class Program
{
static void Main(string[] args)
{
string dllPath = #"C:\Program Files\R\R-3.1.0\bin\i386";
REngine.SetDllDirectory(dllPath);
REngine.CreateInstance("RDotNet");
//REngine engine = REngine.GetInstanceFromID("RDotNet");
using (REngine engine = REngine.GetInstanceFromID("RDotNet"))
{
var x = engine.Evaluate("x <- 1 + 2");
Console.WriteLine(x);
}
}
}
}
but when I try to send the command to R and get back the calue in x I got an error:
"InvalidOperationException was unhandled"
"Operation is not valid due to the current state of the object."
If I explore the object "engine" I see that IsRunning=false.
Can this be the problem? And how can I fix this in order to be able to interface to R?
It looks like you have outdated version of R.NET.
From R.NET project documentation
R.NET 1.5.10 and subsequent versions include significant changes
notably to alleviate two stumbling blocks often dealt with by users:
paths to the R shared library, and preventing multiple engine
initializations.
You can update your R.NET using NuGet manager from Visual Studio. See the same documentation page for detals.
Here is code sample from the same documentatin page - note that initialization of REngine is significantly simpler now (as now Rengine looks at the Registry settings set up by the R installer):
REngine.SetEnvironmentVariables(); // <-- May be omitted; the next line would call it.
REngine engine = REngine.GetInstance();
// A somewhat contrived but customary Hello World:
CharacterVector charVec = engine.CreateCharacterVector(new[] { "Hello, R world!, .NET speaking" });
engine.SetSymbol("greetings", charVec);
engine.Evaluate("str(greetings)"); // print out in the console
string[] a = engine.Evaluate("'Hi there .NET, from the R engine'").AsCharacter().ToArray();
Console.WriteLine("R answered: '{0}'", a[0]);
Console.WriteLine("Press any key to exit the program");
Console.ReadKey();
engine.Dispose();

Thread safe random number/string generator for an OAuth nonce in C#

I've been using an OAuthBase class found HERE in my SSIS 2008 C# Script Components (.NET 3.5).
It's been working fine, but recently I've ran into the problem where if I execute multiple script components in the same Data Flow Task, using the GenerateNonce method in the above OAuthBase class, I end up with the same nonce (random number).
Here's an excerpt from the OAuthBase class that generates the nonce:
using System;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace OAuth {
public class OAuthBase {
....snip......
protected Random random = new Random();
public virtual string GenerateNonce() {
// Just a simple implementation of a random number between 123400 and 9999999
return random.Next(123400, 9999999).ToString();
}
}
}
In each script component I'm using this C# code to initiate the class and generate a nonce:
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
From my searching around I think this is related to it not being thread safe? I'm not totally sure.
I'm only able to run .NET 3.5 in SSIS 2008, so I know some of the newer stuff introduced in .NET 4.0 I can't use.
Any ideas on how I can either modify the OAuthBase class and/or my C# script component code?
If you create multiple instance of OAuthBase at the same time, it is entirely possible that the individual instance will have a Random instance with the same seed, which by default the seed is the current tick count. So this means the individual instances of Random possibly have been created with the same seed. Try making the Random instance static. But since Random is not thread safe. You would need to protect access to it.
private static readonly Random random = new Random();
private static readonly object randLock = new object();
public virtual string GenerateNonce()
{
lock (randLock)
{
// Just a simple implementation of a random number between 123400 and 9999999
return random.Next(123400, 9999999).ToString();
}
}
// since you had protected access on random, I'm assuming sub classes want to use it
// so you'll need to provide them with access to it
protected int NextRandom(...)
{
lock (randLock)
{
random.Next(...);
}
}
But as others have suggested since you don't have a cryptographically strong source of randomness, you may want to look at other ways to generate your value.
// RNGCryptoServiceProvider is thread safe in .NET 3.5 and above
// .NET 3.0 and below will need locking to protect access
private static readonly RNGCryptoServiceProvider random =
new RNGCryptoServiceProvider();
public /*virtual*/ byte[] GenerateNonce(int length)
{
// a default length could be specified instead of being parameterized
var data = new byte[length];
random.GetNonZeroBytes(data);
return data;
}
// or
public /*virtual*/ string GenerateNonce(int length)
{
var data = new byte[length];
random.GetNonZeroBytes(data);
return Convert.ToBase64String(data);
}
This nonce has very few possible values. Even the threading bug aside it is not unique by any means. Use a cryptographically strong source of randomness (http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx), output 16 bytes and base64 them. This takes care of all of that.

Categories

Resources