I am trying to hash a value (SHA1) in both C# and Java, and then return a base64 representation. I get 2 different results.
I know this is because Java uses signed bytes while C# doesn't.
C# version :
static public string toSHA1(string toEncrypt)
{
return toSHA1(toEncrypt, new UTF8Encoding());
}
static public string toSHA1(string toEncrypt, Encoding encoding)
{
String salt = "fE4wd#u*d9b9kdKszgè02ep5à4qZa!éi6";
SHA256Managed sha256hasher = new SHA256Managed();
byte[] hashedDataBytes = sha256hasher.ComputeHash(encoding.GetBytes(toEncrypt + salt));
return Convert.ToBase64String(hashedDataBytes);
}
Java version :
public static String toSHA1(String toEncrypt) {
return toSHA1(toEncrypt, "UTF-8");
}
public static String toSHA1(String toEncrypt, String encoding) {
String salt = "fE4wd#u*d9b9kdKszgè02ep5à4qZa!éi6";
String res = null;
toEncrypt = toEncrypt + salt;
try {
byte[] dataBytes = toEncrypt.getBytes(encoding);
MessageDigest md = MessageDigest.getInstance("SHA-1");
res = Base64.encodeBytes(md.digest(dataBytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return res;
}
I can't manage to find a solution to get the correct base64 result using Java.
Converting signed values to unsigned ones forces the use of int data type, but as soon as I put it in a byte data type, I get my signed bytes back...
Base64.encodeBytes is waiting for a byte array, so is there any way I can pass an unsigned byte array to this method ? What can I do with that int array ? :
int[] dataInt = new int[dataBytes.length];
// signed to unsigned
for (int i=0; i<dataBytes.length; i++)
{
dataInt[i] = (dataBytes[i] & 0xFF);
}
I can't modify the C# version, I have to adapt the Java version to give the same results.
The problem is very simple... From your C# code:
SHA256Managed sha256hasher = new SHA256Managed()
SHA-256 != SHA-1. Use the SHA1 class instead in C#, or use SHA-256 in Java as well. As you apparently can't change the C# code, you should change the Java instead:
MessageDigest md = MessageDigest.getInstance("SHA-256");
Once you've done that, the base64-encoded data should be the same in both platforms. Even though bytes are signed in Java, base64 encoders treat them as unsigned... they're only interested in the bits, basically.
I'd also strongly suggest that you represent your salt in ASCII in the source code, using \uxxxx escaping for any non-ASCII characters. This will prevent problems due to compiling using the wrong encoding.
Related
How can i send illegal charecters from tpc client to tcp server.
This is an example of what the encrypted gibberish looks like:
https://i.stack.imgur.com/wfZdm.png
How can i send this pice of gibberish to either my client or server?
This is my encryption & decryption code
public static string Decrypt(string data)
{
byte[] dataToDecrypt = StringToByteArray(data);
byte[] decryptedData;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(privateKey);
decryptedData = rsa.Decrypt(dataToDecrypt, false);
}
UnicodeEncoding byteConverter = new UnicodeEncoding();
return ByteArrayToString(decryptedData);
}
public static string Encrypt(string data, string publicKey)
{
UnicodeEncoding byteConverter = new UnicodeEncoding();
byte[] dataToEncrypt = StringToByteArray(data);
byte[] encryptedData;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(publicKey);
encryptedData = rsa.Encrypt(dataToEncrypt, false);
}
return ByteArrayToString(encryptedData);
}
public static byte[] StringToByteArray(string data)
{
return Encoding.ASCII.GetBytes(data);
}
public static string ByteArrayToString(byte[] bytes)
{
return Encoding.ASCII.GetString(bytes);
}
I have made it so the client and the server share eachothers public keys but i am getting Exception "Bad data". One more thing if i send encrypted data from a client to the server which data is 128 bytes the server receives only 78 bytes for example
There's a few things wrong with your code:
You shouldn't be using String at all.
String is meant for text, not arbitrary binary data (I assume you got this impression from C or PHP where their string types are really just synonyms for - or thin-wrappers over - a byte-array).
Keep the Byte[] buffer you get from rs.Encrypt and pass that directly to your Socket, TcpClient or NetworkStream that you're using. You'll need to define a binary protocol with length-prefix though.
Encoding.ASCII.GetBytes will convert the UTF-16LE-encoded characters in the String data instance to 7-bit ASCII, it does this by replacing characters with values above 0x7F with '?' - this is not what you want! (and this is what's causing the garbage output on your screen: those "illegal characters" are byte-values above 0x7F that are outside ASCII's 7-bit range. From the documentation:
It uses replacement fallback to replace each string that it cannot encode and each byte that it cannot decode with a question mark ("?") character.
If you really do want to transmit data over the network using human-readable text then use Base64 encoding: Convert.ToBase64String( Byte[] buffer ) and convert it back using Convert.FromBase64String( String s ) at the receiving end - but you'll still need to length-prefix or delimit your data.
I have an application running on c# and another server application in go. I need to implement secure communication using rsa.
What i'am doing is I've initialized the RSA provider in my C# application and generated public key to extract Modulus and Exponent. Then concatenated the modulus (Hexadecimal) and exponent (int) and converted this string to Base64 string, send it to a GO endpoint.
Here is C# code snippet
public string ConvertToPublicKey()
{
CspParameters rsaParameters = GetCspParameters();
RSACryptoServiceProvider provider = newRSACryptoServiceProvider(rsaParameters);
string paramsXml = RsaProvider.ToXmlString(false);
XDocument xDocument = XDocument.Parse(paramsXml);
string modulus = xDocument.Descendants().FirstOrDefault(x => x.Name == "Modulus")?.Value ?? string.Empty;
string exponent = xDocument.Descendants().FirstOrDefault(x => x.Name == "Exponent")?.Value ?? string.Empty;
byte[] base64BytesOfModulus = Convert.FromBase64String(modulus);
string hexaDecimalofModulus = BitConverter.ToString(base64BytesOfModulus).Replace("-", string.Empty);
byte[] base64BytesOfExponent = Convert.FromBase64String(exponent);
string hexadecimalOfExponent = BitConverter.ToString(base64BytesOfExponent).Replace("-", string.Empty);
int intOfExponent = Convert.ToInt32(hexadecimalOfExponent, 16);
byte[] publicKey = Encoding.UTF8.GetBytes($"{hexaDecimalofModulus};{intOfExponent}");
return Convert.ToBase64String(publicKey);
}
private static CspParameters GetCspParameters()
{
const string containerName = "KeyContainer";
return new CspParameters
{
KeyContainerName = containerName,
Flags = CspProviderFlags.UseMachineKeyStore
};
}
At Go endpoint I received public key and modulus correctly. Then I encrypted the message using public key and sent it back to c# application in response after converting encrypted message byte[] to base64.
Here is GO code snippet
func GetLicenseInfo(responseWriter http.ResponseWriter,request*http.Request)
{
encryptionKey := request.Header.Get("Authorization")
var decodedStringBytes, errors = b64.StdEncoding.DecodeString(encryptionKey)
if errors == nil {
var decodedString = string(decodedStringBytes)
result := strings.Split(decodedString, ";")
modulus := new(big.Int)
modulus.SetString(result[0], 16)
exponent, exponentErrors := strconv.Atoi(result[1])
if exponentErrors == nil {
var someInfo = utils.GetInfo()
var InfoInJson = ToJson(someInfo)
publicKey := &rsa.PublicKey{N: modulus, E: exponent}
var encryptedMessage, err = rsa.EncryptOAEP(sha256.New(),rand.Reader, publicKey,[]byte(InfoInJson), []byte(""))
var response = b64.StdEncoding.EncodeToString(encryptedMessage)
if err == nil {
json.NewEncoder(responseWriter).Encode(response)
}
}
}
}
func ToJson(model InfoModel) string {
InfoInJson, errors := json.Marshal(model)
if errors != nil {
panic("An error occurred while serializing the response")
}
return string(InfoInJson)
}
When i received the response back in Base64 string i converted it to Byte[] and tried decrypting that with same instance of RSACryptoServiceProvider then it throws the following exception
Error occurred while decoding OAEP padding.
any help?
UPDATE
for example here is the base64 string that i received in GO
QUQ2NDlFRTlCQTA3Q0IxNEI1MTNDMzczQzBBMjNBOEQyMDI5MkVGQTBFMjgyNUIyMEEyMzM1MEE3OTUyNjgyQ0Y3MEFBQjJBMTZGMzQyNTM4MkU2RDZBRjU5M0IxRTI2MTE0OEIyQkFFRTY3MUVDMTQ1NDk1NjBDRkNEQUNCQzI3RUUxNDRFODZDQUI4RDBDOUY2OENBNTUwNUMxQjZGQkVBQjQ0MTlBMjg3RDhBRjgxRDUyREY3MEM0RDZDQTA5MkREMzk5Q0NEODU5Q0FGQzAzQ0JEQ0JBQzgwOTg3NDY0NThBMkY4NEREOTc1QjU5QTJBMUNBNzQxQTBDNkQ2RDs2NTUzNw==
and here is what my GO app sent back
QuWpWdEPSJR+l9UJTkh+heJJ/NpPwhz/hVVu1VdKYdz37YGWWdKTj7Fc5lZ3A8p1WjtC4F+yieZCz0tEatCqTpRmm9g6Oioyjbtr9qGTxO/PE+GA33YyBe6nmMRe674SPePx/fg6l3nnfSZ4/+iLCV4bNgyNqFHCaXc7H4Snms8=
UPDATE 2
I've updated the code snippet and included the data types and here is the part that dscrypts the content received from GO end point
public byte[] Decrypt(byte[] encryptedData, RSAParameters rsaParameters)
{
RsaProvider.ImportParameters(rsaParameters);
return RsaProvider.Decrypt(encryptedData, true);
}
i receive a base64 string then i convert to byte[] using this
byte[] b = Convert.FromBase64String(responseString); byte[] decryptedBytes=crypto.Decrypt(b, crypto.RsaProvider.ExportParameters(false));
crypto is the instance of the class that contains decryption logic,instacne of RSACryptoServiceProvider and that method(ConvertToPublicKey) given above returning the public key
In go you have
var encryptedMessage, err = rsa.EncryptOAEP(sha256.New(), ...
Which I'll go ahead and assume is OAEP with SHA-2-256.
In C# you have
return RsaProvider.Decrypt(encryptedData, true);
Which is OAEP with SHA-1.
You need to abandon RSACryptoServiceProvider. If you switch to RSACng you can then decrypt it with
using (RSA rsa = new RSACng())
{
rsa.ImportParameters(rsaParameters);
return rsa.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA256);
}
And while I'm here:
In ConvertToPublicKey you export the XML, parse the XML, and turn it into byte arrays. Why not just call ExportParameters(false) and extract the Modulus and Exponent byte arrays directly?
After addressing comments by #bartonjs I've also changed response response from go to
var encryptedMessage, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, []byte(licenseInformationJson), []byte(""))
if err == nil {
responseWriter.Write([]byte(encryptedMessage))
}
Notice []byte(encryptedMessage) byte stream sent from go to c# is slightly changed because encryptedMessage is []unint8. so you need to typecast encryptedMessage to []byte so that values are correctly mapped in c#.
I am encrypting the message in .NET with RSACryptoServiceProvider with private key. (PKCS#1 v1.5)
When I try to decrypt in .NET with the following code that uses public key everything works fine:
private static string Decrypt(string key, string content)
{
byte[] rgb = Convert.FromBase64String(content);
var cryptoServiceProvider = new RSACryptoServiceProvider(new CspParameters()
{
ProviderType = 1
});
cryptoServiceProvider.ImportCspBlob(Convert.FromBase64String(key));
return Convert.ToBase64String(cryptoServiceProvider.Decrypt(rgb, false));
}
When on the other hand I try to find an algorithm to make the same decrypt method in Android, I am failing to decrypt it properly with public key. I exported the modulus and exponent from public key in .NET in order to load it properly on Android.
The method in Android is here:
public String Decrypt(String input) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
String modulusString = "mmGn1IXB+/NEm1ecLiUzgz7g2L6L5EE5DUcptppTNwZSqxeYKn0AuAccupL0iyX3LMPw6Dl9pjPXDjk93TQwYwyGgZaXOSRDQd/W2Y93g8erpGBRm/Olt7QN2GYhxP8Vn+cWUbNuikdD4yMfYX9NeD9UNt5WJGFf+jRkLk0zRK0A7ZIS+q0NvGJ/CgaRuoe3x4Mh1qYP9ZWNRw8rsDbZ6N2zyUa3Hk/WJkptRa6jrzc937r3QYF3eDTurVJZHwC7c3TJ474/8up3YNREnpK1p7hqwQ78fn35Tw4ZyTNxCevVJfYtc7pKHHiwfk36OxtOIesfKlMnHMs4vMWJm79ctixqAe3i9aFbbRj710dKAfZZ0FnwSnTpsoKO5g7N8mKY8nVpZej7tcLdTL44JqWEqnQkocRqgO/p3R8V/6To/OjQGf0r6ut9y/LnlM5qalnKJ1gFg1D7gCzZJ150TX4AO5kGSAFRyjkwGxnR0WLKf+BDZ8T/syOrFOrzg6b05OxiECwCvLWk0AaQiJkdu2uHbsFUj3J2BcwDYm/kZiD0Ri886xHqZMNExZshlIqiecqCskQhaMVC1+aCm+IFf16Qg/+eMYCd+3jm/deezT4rcMBOV/M+muownGYQ9WOdjEK53h9oVheahD3LqCW8MizABFimvXR3wAgkIUvhocVhSN0=";
String exponentString = "AQAB";
byte[] modulusBytes = Base64.decode(modulusString.getBytes("UTF-8"), Base64.DEFAULT);
byte[] dBytes = Base64.decode(exponentString.getBytes("UTF-8"), Base64.DEFAULT);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger d = new BigInteger(1, dBytes);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, d);
PublicKey key = keyFactory.generatePublic(keySpec);
//at one point I read somewhere that .net reverses the byte array so that it needs to be reversed for java, but who knows any more
/*byte[] inputArrayReversed = Base64.decode(input.getBytes("UTF-8"), Base64.DEFAULT);
for (int i = 0; i < inputArrayReversed.length / 2; i++) {
byte temp = inputArrayReversed[i];
inputArrayReversed[i] = inputArrayReversed[inputArrayReversed.length - 1];
inputArrayReversed[inputArrayReversed.length - 1] = temp;
}*/
byte[] decryptedText = null;
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedText = cipher.doFinal(Base64.decode(input.getBytes("UTF-8"), Base64.DEFAULT));
return Base64.encodeToString(decryptedText, Base64.NO_WRAP);
//return new String(decryptedText, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
Actually I tried also with different algorithms specified in Cypher class, also tried many other combinations, tried using SpongyCastle instead of built in Android RSA providers, but nothing worked. If anybody has any clue to point me in right direction, I would be absolutely grateful.
First hint is that decrypted string from .NET comes as around 25 characters long, and when I get Android to return decrypted string without exceptions it is usually much longer, around 500 bytes.
Second hint deleted
Third hint I also tried spongycastle, but it didn't help that much
Anyways, thank you in advance for any help!!!
UPDATE 1
Second hint is deleted because was wrong, disregard it. Now I have one question if the following can prove that the public key is loaded correctly, just to rule that problem out.
BigInteger modulus and exponent in the upper Android code and the following BigIntegers in .NET show equal integer values.
var parameters = csp.ExportParameters(false);
var modulusInteger = new BigInteger(parameters.Modulus.Reverse().Concat(new byte[] { 0 }).ToArray());
var exponentInteger = new BigInteger(parameters.Exponent.Reverse().Concat(new byte[] { 0 }).ToArray());
UPDATE 2
This and This SO answers provide some interesting clues
Heeh, the mistake was one of the basics, we had an architecture where we were doing encryption with public key and decryption with private key. The problem was in the architecture itself because as we initially set it up, we were sending private keys to all our client apps, which is big security flaw.
My mistake was that I assumed that on the client we have public key and actually from private key all the time I was trying to load the public key and then do decrypt.
If I knew the PKI in depth and communicated a bit better with my colleague, I could have noticed few things:
Decrypt can be done with private key only, while one the other hand verify can be done with public key, so when I saw Decrypt being used on client in .NET, I should have assumed that on the client we have private key (which is a security flaw in the end in the way we want to use PKI)
Few things that I already knew or learnt and want to share with others:
Private key should be kept secret, whether you want to have it on server or preferably only on one client because public key can easily be guessed from private key and then someone can easily repeat your whole encryption process easily and breach your security
PKI works for two scenarios:
First scenario is when you want to Encrypt something and that only specific person/computer can Decrypt it. In first scenario as you see, many stakeholders can have someone's Public key and send messages to him and that only he can read them with his Private key. Second scenario is when you want to be sure that the message that came to you was not altered and was sent by specific person/computer. In that case you Sign data with Private key and Verify it on the other end with Public key. The only process that is suitable for us is Sign <-> Verify because we send plain text license with signature in it, and thus on the client we want to be sure that nobody tampered with the plain text license and that it came from us.
In your code, if Decrypt or Verify functions throw exceptions in 50% of the time it is because of loading the incorrect key or incorrectly loading the correct key and in the other 50% it is because you are using the incorrect algorithm or because algorithm parameters are incorrectly set or because the algorithm implementations between platforms are incompatible (the last one is very rare)
.NET server code
public string Sign(string privateKey, string data)
{
_rsaProvider.ImportCspBlob(Convert.FromBase64String(privateKey));
//// Write the message to a byte array using UTF8 as the encoding.
var encoder = new UTF8Encoding();
byte[] byteData = encoder.GetBytes(data);
//// Sign the data, using SHA512 as the hashing algorithm
byte[] encryptedBytes = _rsaProvider.SignData(byteData, new SHA1CryptoServiceProvider());
return Convert.ToBase64String(encryptedBytes);
}
.NET client code (Win Mobile)
private bool Verify(string key, string signature, string data)
{
CspParameters cspParams = new CspParameters { ProviderType = 1 };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(key));
byte[] signatureBytes = Convert.FromBase64String(signature);
var encoder = new UTF8Encoding();
byte[] dataBytes = encoder.GetBytes(data);
return rsaProvider.VerifyData(dataBytes, new SHA1CryptoServiceProvider(), signatureBytes);
}
Android client code:
public boolean Verify(RSAPublicKey key, String signature, String data)
{
try
{
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initVerify(key);
sign.update(data.getBytes("UTF-8"));
return sign.verify(Base64.decode(signature.getBytes("UTF-8"), Base64.NO_WRAP));
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
in .NET public key is exported in xml format with following code:
public string ExportPublicToXML(string publicKey)
{
RSACryptoServiceProvider csp = new RSACryptoServiceProvider(new CspParameters()
{
ProviderType = 1
});
csp.ImportCspBlob(Convert.FromBase64String(publicKey));
return csp.ToXmlString(false);
}
and then modulus and exponent are used in Android to load public key:
private RSAPublicKey GetPublicKey(String keyXmlString) throws InvalidKeySpecException, UnsupportedEncodingException, NoSuchAlgorithmException
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
String modulusString = keyXmlString.substring(keyXmlString.indexOf("<Modulus>"), keyXmlString.indexOf("</Modulus>")).replace("<Modulus>", "");
String exponentString = keyXmlString.substring(keyXmlString.indexOf("<Exponent>"), keyXmlString.indexOf("</Exponent>")).replace("<Exponent>", "");
byte[] modulusBytes = Base64.decode(modulusString.getBytes("UTF-8"), Base64.DEFAULT);
byte[] dBytes = Base64.decode(exponentString.getBytes("UTF-8"), Base64.DEFAULT);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger d = new BigInteger(1, dBytes);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, d);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
}
I require a certain piece of encryption logic done in Java to be converted to C#
What would be the C# equivalent for the MessageDigest update , Digest and reset functions ?
In C#, the class is HashAlgorithm.
The equivalent to update is either TransformBlock(...) or TransformFinalBlock(...), after the final block version is called (you can also use an empty input) you can call the Hash property that will give you the digest value.
HashAlgorithm is likely to be reusable after final block is called (which means it is reset for the next time you call TransformBlock), you can double check if your HashAlgorithm supports reusing at all by checking the property CanReuseTransform.
The equivalent to your reset()/digest() combo is a one line byte[] ComputeHash(byte[]).
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(password.getBytes());
BigInteger hash = new BigInteger(1, md.digest());
hashword = hash.toString(16);
} catch (NoSuchAlgorithmException ex) {
/* error handling */
}
return hashword;
public static string HashPassword(string input)
{
var sha1 = SHA1Managed.Create();
byte[] inputBytes = Encoding.ASCII.GetBytes(input);
byte[] outputBytes = sha1.ComputeHash(inputBytes);
return BitConverter.ToString(outputBytes).Replace("-", "").ToLower();
}
For a Digest in C#, similar to Java, you can use the class Windows.Security.Cryptography.Core. E.g., the following method returns a SHA256 hash, formatted in base64:
public static string sha256Hash(string data)
{
// create buffer and specify encoding format (here utf8)
IBuffer input = CryptographicBuffer.ConvertStringToBinary(data,
BinaryStringEncoding.Utf8);
// select algorithm
var hasher = HashAlgorithmProvider.OpenAlgorithm("SHA256");
IBuffer hashed = hasher.HashData(input);
// return hash in base64 format
return CryptographicBuffer.EncodeToBase64String(hashed);
}
See (mbrit): How to create SHA-256 hashes in WinRT?
I was hoping I might get some help here so that I might finally solve this frustrating problem.
On the java side of things they sign with the following code:
public static void main(String[] args) throws Exception {
if (args.length < 2)
printInfoAndExit();
String cmd = args[0];
Security.addProvider(new BouncyCastleProvider());
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
if ("sign".equalsIgnoreCase(cmd)) {
String pemFileName = args[1];
String dataFileName = args[2];
byte[] data = readFile(dataFileName);
FileReader fr = new FileReader(new File(pemFileName));
PEMReader pemReader = new PEMReader(fr);
KeyPair keyPair = (KeyPair) pemReader.readObject();
fr.close();
signature.initSign(keyPair.getPrivate());
signature.update(data);
byte[] signatureBytes = signature.sign();
writeFile(signatureBytes, dataFileName + ".signed");
String encoded = Base64.encode(signatureBytes);
writeFile(encoded.getBytes(), dataFileName + ".signed.base64");
} else {
printInfoAndExit();
}
}
When I receive the data I have their public key and try to verify with the following C# code:
public static bool Verify(String msg, String signature, String publicKey)
{
RsaKeyParameters remotepubkey = GetRsaPublicKey(publicKey);
ISigner signer = SignerUtilities.GetSigner("SHA1withRSA");
signer.Init(false, remotepubkey);
byte[] sigBytes = Convert.FromBase64String(signature);
byte[] msgBytes = Encoding.Default.GetBytes(msg);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(sigBytes);
}
This is not working!! I can however verify the data with openssl:
openssl dgst -sha1 -verify public_key.pem -signature data.txt.signed data.txt
The question is, what am I missing to make this work?
NOTE: I don't have a problem with the keys, that is working correctly but somehow there is a difference between how java and .net works with RSA?
**Edit 1 : **In this particular scenario all I had to do was change the GetSigner to
ISigner signer = SignerUtilities.GetSigner("RSA");
Could someone tell me the difference between SHA1withRSA and RSA?
The problem was actually solved on the Java side. They had some issues with their side of things.
You could have an encoding problem with your message data. You've converted the original file data into a unicode string, and are trying to convert it back to raw bytes. Depending on the encoding of the file, and if it's even text at all, your msgBytes could be different from the actual file contents.
Read the raw bytes from the file instead of a string. You don't show the code for actually reading the file data, but I assume you're reading it as text.