This thread should not be for discussion on how bad ECB mode is, and that I should change it, but that BouncyCastle doesn't really support the mode, except for in Java, where you can use "getInstance". The code I am using is this, and it only decrypts the first block(0x1000 bytes) correctly.
BufferedBlockCipher Blowfish = new BufferedBlockCipher(new BlowfishEngine());
KeyParameter r3 = new KeyParameter(Blowfish_Key);
Blowfish.Init(false, r3);
Blowfish.ProcessBytes(pio.GetBuffer(), 0, (int)pio.Length, output, 0);
I guess the question here would be, is there a way to use ECB mode with the library, or are there any other classes I could use?
Figured it out. My file was probably corrupt, since I downloaded it again and it worked successfully.
Related
I'm trying to implement Blowfish encryption, ECB mode, through BouncyCastle. The problem is that this code encrypts only first 8 bytes of the file. I don't know, what the problem might be. I've worked with BouncyCastle before.
I found that I'm not the one having this problem, but the solution here didn't help:
Blowfish ECB Mode in BouncyCastle
The code is:
byte[] fileIn = File.ReadAllBytes("file.txt"), fileOut = new byte[fileIn.Length];
BlowfishEngine blowfishEngine = new BlowfishEngine();
blowfishEngine.Init(true, new KeyParameter(Encoding.UTF8.GetBytes("ahoi")));
blowfishEngine.ProcessBlock(fileIn, 0, fileOut, 0);
File.WriteAllBytes("file2.txt", fileOut);
I am writing an application where I need to encrypt, sign and wrap some content into a PKCS7/CMS structure. I am using OpenSSL.NET for the task (Wrapper for .NET).
I don't have much yet, I have successfully encrypted some data but
RSA toServer = cert.Certificate.PublicKey.GetRSA();
RSA fromClient = cert.Certificate.PublicKey.GetRSA();
byte[] cipherText = toServer.PublicEncrypt(Encoding.UTF8.GetBytes("Hello World!"), RSA.Padding.PKCS1);
byte[] plainText = fromClient.PrivateDecrypt(cipherText, RSA.Padding.PKCS1);
This works, it successfully encrypts and decrypts the data, but now I want to move further and implement PKCS7/CMS so that I have a standard format for my messages. I have found the below object that seem to point in the right direction but I fail to find some documentation on how to use it:
OpenSSL.X509.PKCS7 p7 = new OpenSSL.X509.PKCS7( ? );
Any suggestions or references to documentation are welcome.
I'm trying to write a service to SFTP to a server on a given interval, download all files in a directory, and then decrypt them for processing.
The decrypt method was working at one point, and I have no modified it since. I am still using the same keys as when it did successfully work.
I am using the PGPEncrypt, PGPDecrypt, and PGPEncryptionKeys classes for BouncyCastle found here: https://github.com/sledwith/PGP-Decryption-With-C-Sharp
Additionally, I have modified the code as shown here: Exception on decrypting file using BouncyCastle PGP
If you noticed, I commented on how that fixed my code and the decryption worked.
Now, it isn't.
Does anyone have some insight why this might have happened, or how I could go about fixing it?
I am going to make a guess that you are using a 1024 bit RSA public/private key and trying to encrypt 128 bytes of something with it? If I am right, use a larger RSA key (RSA 4096 will allow you to encrypt up to ~500 bytes).
I note in the linked post you say this is sporadic. Some googling indicates that if you have leading zeros in the to-be-encrypted bytes it may be able to handle a full 128 bytes.
Also - if you are just encrypting "data" with the keypair, you need to be certain it will not overrun these limitations (240 or so bytes for RSA 2048 and 500 or so for RSA 4096 accounting for padding). Good practice and future proofing would be to implement a symmetric key encryption of all your data and just use the RSA key to encrypt / decrypt your keys.
If you're not dead-set on using the PGP process explicitly, you might use my library here:
https://github.com/zenith-nz/ObscurCore
Its "banner feature" is not yet fully active (creating encrypted archives of a kind), but it does everything that you want it for, it appears - it does key derivation with a ECDHC scheme, UM1, and implements a large variety of block and stream ciphers. It's built on top of BouncyCastle.
I think I resolved this problem; please try this code.
public string StringToDecrypt(string text)
{
byte[] toDecrypt = Convert.FromBase64String(text);
AsymmetricCipherKeyPair keyPair;
using (var reader = File.OpenText(#"Private Key File Path"))
{
keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject();
}
var engine = new RsaEngine();
engine.Init(false, keyPair.Private);
return Encoding.UTF8.GetString(engine.ProcessBlock(toDecrypt, 0, toDecrypt.Length));
}
I'm trying to generate a authentication-tag in C# which I already generated in Ruby (for testing purposes). However the results are different, but as far as I can see,the inputs are equal.
In Ruby 2.0 using OpenSSL 1.0.1c (Ubuntu 13.04):
require 'openssl'
require 'base64'
iv = Base64.decode64('kEWio77T7qWdytrIbUmRxA==')
key = Base64.decode64('FnUoIZvBUzC1Q/rn5WMi7Q==')
aad = Base64.decode64('/tTP07sPkoX8gah60eH89w==')
cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt
cipher.iv = iv
cipher.key = key
cipher.auth_data = aad
cipher.final
tag = Base64.strict_encode64(cipher.auth_tag)
The resulting (encoded) tag is ie74XTWtSLNad0BKdrhvmQ==
In C# using BouncyCastle (snippet):
var iv = Convert.FromBase64String("kEWio77T7qWdytrIbUmRxA==");
var key = Convert.FromBase64String("FnUoIZvBUzC1Q/rn5WMi7Q==");
var aad = Convert.FromBase64String("/tTP07sPkoX8gah60eH89w==");
var cipher = new GcmBlockCipher(new AesFastEngine());
var parameters = new AeadParameters(new KeyParameter(passkey), 128, iv, aad);
cipher.Init(true, parameters);
var cipherText = new byte[cipher.GetOutputSize(0)];
cipher.DoFinal(cipherText, 0);
var tag = Convert.ToBase64String(cipher.GetMac());
The resulting tag in C# is sawCcwM1T8sGl5y6VT0CHA==
What am I doing wrong here? Thanks in advance for your response!
Okay, I installed ruby 2.0.0 and did some tests.
First of all, to replicate your original output "ie74XTWtSLNad0BKdrhvmQ==" in C#, set the IV in C# to "new byte[12]".
The reason that works, is that in the ruby code setting cipher.key clears whatever IV you set, so the effective IV is the default all-zeroes of default length (96 bits for GCM). So you should set the IV after the key.
If we change the ruby code to do that, then the output changes to "d1tAJ6Js94tSuPNbds0EJw=="; still not a match. To reproduce this value in C#, truncate the IV to 12 bytes, i.e. "kEWio77T7qWdytrI", and the output now matches.
From this I infer that openssl/EVP is truncating any IV you give it. That shouldn't strictly be necessary, as GCM does support longer IVs, but 96 bits is in some sense the "preferred" length; I'm not sure where that policy is being enforced here.
I am working on a feature that needs me to digitally sign a short string in PHP, and verify the string's signature in C#.
I would really like to use openssl_sign in PHP, because of its simplicity, but all the information I can find on Google indicates that this will not work.
There are some external libraries that claim to do this well, however as this is a hobby project I would rather not purchase such a library.
So what are the alternatives here? Full interoperability between C# and PHP is required. Libraries besides OpenSSL can be used.
I've done something very similar using Bouncy Castle Crypto APIs. It appears PHP openssl_sign uses SHA1 by default. If you are using anything other than the default you'll need to change the algorithm parameter for GetSigner.
string base64pubkey = "<!-- BASE64 representation of your pubkey from open ssl -->";
RsaKeyParameters pubKey = PublicKeyFactory.CreateKey(Convert.FromBase64String(base64pubkey)) as RsaKeyParameters;
byte[] signature = Convert.FromBase64String("<!-- BASE64 representation of your sig -->");
byte[] message = Encoding.ASCII.GetBytes("Something that has been signed");
ISigner sig = SignerUtilities.GetSigner("SHA1WithRSAEncryption");
sig.Init(false, pubKey);
sig.BlockUpdate(message, 0, message.Length);
if (sig.VerifySignature(signature))
{
Console.WriteLine("all good!");
}
You may use to check the digital signature smth like this:
string publicKey = "some key";
// Verifying Step 1: Create the digital signature algorithm object
DSACryptoServiceProvider verifier = new DSACryptoServiceProvider();
// Verifying Step 2: Import the signature and public key.
verifier.FromXmlString(publicKey);
// Verifying Step 3: Store the data to be verified in a byte array
FileStream file = new FileStream(args[0], FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(file2);
byte[] data = reader.ReadBytes((int)file2.Length);
// Verifying Step 4: Call the VerifyData method
if (verifier.VerifyData(data, signature))
Console.WriteLine("Signature verified");
else
Console.WriteLine("Signature NOT verified");
reader.Close();
file.Close();
Is there a reason you need something as complex as SSL signing? Can't you just use a simple one-way hash like MD5/SHA-1 on the string? If all you're looking for is verification that the string wasn't tampered with, that should be sufficient.
So looking at this - this guy appears to have asymmetric signing and encrypting working between PHP and C#. Signing should not be a problem, SHA* and MD* are standard, and so it's very very unlikely that is going to not be compatible (although you should be looking at SHA256 as MD* and SHA1 are deprecated due to vulnerabilities)
We're missing some context as to why you need to sign it. You may not need to.
The important question is: what guarantees do you need from your data?
If all you need to do is verify the integrity of the data, a hash will do the job. If you need to verify where it's coming from, you need to sign it. If you need both, hash it, concatenate the payload with the hash, and sign the whole thing.
Regarding cross-platform libraries... you really should need to worry about it. A SHA1 is a SHA1 is a SHA1, no matter which library generated it. Same thing with generating and verifying digital signatures. Use what's easiest in PHP and use what's easiest in C#. If they're both set up correctly you shouldn't need to worry about it.