Wikipedia:Reference desk/Archives/Computing/2015 July 15

From Wikipedia, the free encyclopedia
Computing desk
< July 14 << Jun | July | Aug >> July 16 >
Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is an archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


July 15[edit]

Netbook replacement[edit]

While I was napping, the netbook disappeared from the market. I'm looking to replace a Toshiba NB505 with something similar--small, light, (almost) full keyboard, not hot on the family jewels. Anyone have any suggestions? Thanks! Drmies (talk) 15:28, 15 July 2015 (UTC)[reply]

I bought something like this from Tesco last year and am quite happy with it. There are other similar machines on that page that you could compare it with.--Phil Holmes (talk) 16:14, 15 July 2015 (UTC)[reply]
Thanks Phil Holmes. So, about terminology, I'm looking for a small laptop, I suppose? Or is "notebook" a valid technical search term? Hard to see the forest for the trees. Drmies (talk) 17:46, 15 July 2015 (UTC)[reply]
As far as I know "notebook" and "laptop" are pretty synonymous. So yes, just a small one of those. As far as the fate of the netbook goes, things that have usurped its its place in the market include the ultrabook (like a netbook but more expensive), the Chromebook (a netbook that only runs web apps) and the convertible tablet. —Noiratsi (talk) 06:49, 16 July 2015 (UTC)[reply]

Blockchain technology to authenticate documents[edit]

Some companies offer "proof of existence" services, and claim that they use blockchain authentication to timestamp documents. As I understand, this is the same technology used to bitcoin. From a technical perspective, is this a 100% sure-fire way of authenticating documents? And, from a legal perspective, do courts recognize this 100% sure-fire (if at all) way of authenticating documents?--Yppieyei (talk) 15:46, 15 July 2015 (UTC)[reply]

They don't just use blockchain technology, they literally store a hash in Bitcoin's blockchain. Bitcoin allows arbitrary data to be added to the blockchain (which has to be stored by every full node in the Bitcoin network forever, which seems wasteful, but oh well).
There's no such thing as a mathematically airtight proof of this sort of thing. It comes down to whether the person you're trying to convince buys your argument. I would personally have complete confidence in the integrity of anything stored in the blockchain that's more than, say, 1 week old, but you might have trouble explaining to a less technically-minded person that they should trust it. You might be better off, say, buying ad space in a widely-read newspaper and putting the hash in that, though you still have to convince them that the hashing algorithm you used is unforgeable.
I don't know whether these sorts of proofs have been tested in court. -- BenRG (talk) 21:03, 15 July 2015 (UTC)\[reply]
OK, I thought they were creating an independent blockchain just for storing the signatures of their digital content. I also had the impression so far that everything older than 1 h could be trusted, but you talk about 1 w.
So, but if stored information starts to grow and grow by bitcoin transactions or "timestampers" performing phony bitcoin transactions, or 2.5 megabyte Wikileak files, wouldn't that be not only wasteful, but reach an amount of information too big to be manageable?
At least, for those of us that are not Google. Isn't bitcoin too easy to disrupt? Would start sending junk into it and see how nodes have to stop working? (starting by the smallish, and then the going up).--Yppieyei (talk) 23:00, 15 July 2015 (UTC)[reply]
I said one week just because it's long enough that no one could argue that I should have picked a longer time, but also short enough that no one would be likely to need to prove that they had a document less than that time ago. I'd probably trust day-old transactions too, but I don't think I'd need to for this application.
The growth of the blockchain is currently limited to 1 megabyte per 10 minutes. If your junk plus legitimate transactions exceeds that rate, the miners choose what to include, and they'd probably choose whatever has the highest transaction fee per byte. Transactions fees currently seem to total around 15 BTC/day (≈ 4000 USD/day), so I suppose you could significantly disrupt the system if you were willing to pay more than that. -- BenRG (talk) 02:30, 16 July 2015 (UTC)[reply]
And besides this limitation of growth speed (of 1MB/h), is there other limitations in size? Maybe a total limitation of gigas? Because if there is, and they are including just the sha256 (64 bytes) or the md5 (8 bytes), then, the whole time-stamping might be useless. Or a total limitation of participants? --Yppieyei (talk) 08:41, 16 July 2015 (UTC)[reply]
There are no other limits that I know of. The block chain can grow forever. Also, the per-block (=per-10-minute) limit will probably be increased in the future. I don't understand your statement about time stamping being useless. (By the way, MD5 and SHA-256 digests are 16 and 32 bytes respectively. Also, using MD5 for proof of possession is probably a bad idea (unconvincing) because collisions have been found.) -- BenRG (talk) 19:05, 19 July 2015 (UTC)[reply]
Thanks for correcting me on the number of bytes. I mean, timestamping services built upon the bitcoin blockchain might be useless. Reliable timestamps are essential for any legal stuff, be it filling a patent or pressing charges or registering a copyright. I was wondering whether there are better ways of decentralized timestamping besides using the blockchain. If loads of people start to try to post their hashes to it around the world, these restriction of 1 mb/10 min (or any future increased capacity) might imply that many will have to wait to get their digital documents timestamped. Besides this, there is still the question whether courts accept this kind of evidence. This question is not appropriate for the ref. desk, but I doubt there is a single case where judges accept anything like this.--Yppieyei (talk) 21:43, 19 July 2015 (UTC)[reply]
YOu can timestamp your documents with the e-signature tools in Acrobat. And you can read about several technical solutions in Trusted_timestamping. An alternative to bitcoin is namecoin, which is a fork of the first, but will suffer the same drawbacks as a proof of existence tool. The whole bitcoin timestamping thing seems as silly as the Poor man's copyright method.--Scicurious (talk) 01:20, 20 July 2015 (UTC)[reply]

Encrypt text that can be decrypted using a key in C#?[edit]

Hello everyone. I am trying to encrypt a string of text. I have been successful at encrypting text, but I can't seem to decrypt it. So I did a little research and found that I need to use a Public key encryption algorithm. Therefore, I came to the RSA algorithm. the .NET Framework has a class for implementing RSA. What I want to know is, who do I use the System.Security.Cryptography.RSA class? I know how to convert text into an array of bytes but I don't know how to use the RSA class. If there are any simpler methods to do what I want to do then please let me know. Thanks for your help in advance. —SGA314 I am not available on weekends (talk) 15:59, 15 July 2015 (UTC)[reply]

It's not really clear what you want. What is your goal or use case? First, public key methods are really good for some purposes, but you don't really need that if you don't need to have people be able to send you encrypted files. The whole point of public key methods was to solve the key distribution problem, but that mostly goes away if you only want to encrypt/decrypt strings for your own local use, or if you have some other secure method of getting keys to people. Also, it seems like you're taking a DIY approach - is there a reason for that? Otherwise you can just use one of the tools like Veracrypt. SemanticMantis (talk) 16:27, 15 July 2015 (UTC)[reply]
A. I like DIY. For me, doing stuff like this is fun. That's why I am taking a DIY approach.
B. My purpose is to use an algorithm to encrypt a string of plaintext. Then use a special key that was used to encrypt the text, to decrypt it. This would allow me to encrypt files and such. —SGA314 I am not available on weekends (talk) 17:01, 15 July 2015 (UTC)[reply]
Why not XOR the string with digits of pi? Your key is which digit of pi to start at as an offset. This constitutes a symmetric key algorithm and it is surprisingly secure against a wide variety of attacks. It's sort of a one-time pad, except that the pad is well-known.
The exercise for you would be to figure out how to represent the n-th digit of pi; and how to ensure that your representation will accurately obfuscate your plaintext. (Hint: if you use ASCII to represent decimal digits of pi, that will leave a lot of bits un-touched - so you'll want to use a different representation)! (Hint #2: if you use a small offset as your key, the digits of pi are very well-known, so that leaves you vulnerable to a category of brute-force attacks).
Nimur (talk) 19:53, 15 July 2015 (UTC)[reply]
That's not a one-time pad; it's a very, very, very slow stream cipher. It also lacks integrity protection, and it's not secure against key reuse—every message encrypted under a particular key will use the same digits of pi. Please don't try to fix those problems; instead, use code written by professional cryptographers. -- BenRG (talk) 20:08, 15 July 2015 (UTC)[reply]
BenRG's main criticism is correct; you should use standard techniques, instead of trying to "work around" all the problems that arise when you use simplistic methods. However, calculating the n-th digit of pi need not be very slow: many algorithms can compute the n'th digit: the most famous of these is the BBP formula and it can run in constant time. This being the case, you can use the digits as a stream cipher with arbitrary (and very large) offset, which is a darned good approximation of a one-time pad. As an exercise in fun mathematics, this is worth consideration. As an effective and cryptologically-sound cypher, ... it leaves a few things to be desired. Nimur (talk) 21:05, 15 July 2015 (UTC)[reply]
According to the paper, the complexity of computing the nth digit of pi with BBP is O(n log(n) M(log(n))) where M(j) is the complexity of multiplying j-bit integers. This is slower than O(n), so encrypting or decrypting using this algorithm is slower than brute-forcing AES. I think it's also almost as slow as brute-forcing the pi-based encryption by generating pi from the beginning. -- BenRG (talk) 01:01, 16 July 2015 (UTC)[reply]
You are correct, thank you for fact-checking my statement. I was in error; BBP to determine the n-th digit of pi is not a constant-time calculation. Nimur (talk) 01:27, 16 July 2015 (UTC)[reply]
Public-key cryptography, aka asymmetric cryptography, uses different keys for encryption and decryption. If you want to decrypt the text with the same key you used to encrypt it, that's symmetric cryptography.
Cryptography is not a good thing to do yourself, because it's very easy to get something wrong, and there's no way to tell when you've done it wrong, because you don't get an error message, just an "encrypted" document that isn't actually secure.
If you want to write your own encryption software, I strongly recommend you use NaCl's crypto_secretbox instead of .NET's built-in libraries. It's much easier to use and much harder to screw something up. There's a .NET version of NaCl here (I haven't used it but it looks decent).
If you want to screw around with low-level stuff like RSA, the best way might be to implement someone else's encrypted format, such as a subset of PGP, and then check your implementation against an official one. If they can decrypt each other's encrypted files, you've mostly gotten the encryption right. Even then you can screw it up, though, by using low-quality randomness when encrypting or by failing to check the integrity when decrypting. -- BenRG (talk) 20:08, 15 July 2015 (UTC)[reply]
Then I guess I need to use an symmetric cryptography. —SGA314 I am not available on weekends (talk) 15:38, 16 July 2015 (UTC)[reply]
My purpose in this is to encrypt messages that I will send to another computer on the net or the local network. That way a hacker can't intercept these messages(they will contain code that will manipulate the pc on the other side) and modify their contents and/or send them back to me. I was planning on having pc A send a message that contains a password that is the hash product of the message contents. Or worse, send malicious code to me! To illustrate my theoretical encryption scheme, lets say that I have a message saying, "Hello." The key would be produced by encrypting the "Hello"(this message will be encrypted using another hard-coded key) message using a hard-coded key. Then when pc B receives the message, it will try and recreate the password using the decoded message. If the recreated password matches the password that was received, then it will run the code(the contents of the message). If anyone has a better idea please let me know. —SGA314 I am not available on weekends (talk) 17:00, 16 July 2015 (UTC)[reply]
Ok so I have come up with an implementation of the Aes algorithm. but when I type in more than the block size can handle(16) then the program errors out saying that it received an incomplete block. To get around this, I have to pad the input bytes with zero bytes. Using this method, when ever i try to decrypt a message, anything past the 16th byte is just garbled nonsense. This is because the program is encrypting the zero bytes(the padding) how do I fix this? Code is below.
Long code
		//this.EncryptedText = a byte array that contains the encrypted text in bytes.
		//OutputBox = a Mutli-line textbox that displays the encrypted text.
                using System.Security.Cryptography;

                public Aes cry = System.Security.Cryptography.AesManaged.Create();
		private void Decrypt()
		{

			ICryptoTransform DeCrypt = cry.CreateDecryptor(this.Key, this.IV);

			byte Bit = byte.Parse("0");

			#region Pad Data To A 16-bit Block
			int Length = this.EncryptedText.Length;
			if (Mod(this.EncryptedText.Length, 16) != 0)
			{
				while (Mod(Length, 16) != 0)
				{
					Length += 1;
				}
			}
			byte[] Input = (byte[])Array.CreateInstance(Bit.GetType(), Length);

			for (int i = 0; i < this.EncryptedText.Length; i++)
			{
				Input[i] = this.EncryptedText[i];
			}
			#endregion
			byte[] Output2 = DeCrypt.TransformFinalBlock(Input, 0, Input.Length);

			DataBox.Text = ConvertBytesToString(Output2);
		}

		private int Mod(int x, int y)
		{
			return x - (x / y) * y;
		}

		private byte[] getChars()
		{
			ICryptoTransform Crypt = cry.CreateEncryptor(cry.Key, cry.IV);
			byte Bit = byte.Parse("0");

			char[] Chars = InputBox.Text.ToCharArray();
			int Length = 0;
			if (Mod(Chars.Count(), Crypt.OutputBlockSize) == 0)
			{
				Length = Chars.Count();
			}
			else
			{
				int a = Mod(16, 16);
				int L = Chars.Count();
				while (Mod(L, Crypt.OutputBlockSize) != 0)
				{
					L += 1;
				}
				Length = L;
			}

			byte[] Input = (byte[])Array.CreateInstance(Bit.GetType(), Length);

			for (int i = 0; i < Chars.Count(); i++)
			{
				Input[i] = (byte)Chars[i];
			}
			return Input;
		}
		private void Encrypt()
		{
			//Generate a Random Key.
			cry.GenerateKey();
			cry.GenerateIV();


			this.Key = cry.Key;
			this.IV = cry.IV;

			ICryptoTransform Crypt = cry.CreateEncryptor(cry.Key, cry.IV);

			byte Bit = byte.Parse("0");

			char[] Chars = InputBox.Text.ToCharArray();
			int Length = 0;
			if (Mod(Chars.Count(), Crypt.OutputBlockSize) == 0)
			{
				Length = Chars.Count();
			}
			else
			{
				int a = Mod(16, 16);
				int L = Chars.Count();
				while (Mod(L, Crypt.OutputBlockSize) != 0)
				{
					L += 1;
				}
				Length = L;
			}

			byte[] Input = getChars();

			byte[] Output = (byte[])Array.CreateInstance(Bit.GetType(), Length);


			Crypt.TransformBlock(Input, 0, Crypt.InputBlockSize, Output, 0);

			this.EncryptedText = Output;

			OutputBox.Text = ConvertBytesToString(Output);

			KeyBox.Text = ConvertBytesToString(cry.Key);
		}
		private string ConvertBytesToString(byte[] Bytes)
		{
			char[] Chars = UnicodeEncoding.UTF7.GetChars(Bytes);
			string Output = String.Empty;
			for (int i = 0; i < Chars.Count(); i++)
			{
				Output += Chars[i];
			}
			return Output;
		}
How would I fix this? —SGA314 I am not available on weekends (talk) 19:13, 16 July 2015 (UTC)[reply]
For all that work, which is prone to error, it makes me wonder why you don't just use Java's native secure socket connection. Then, you don't have to encrypt/decrypt anything. 209.149.113.45 (talk) 19:13, 16 July 2015 (UTC)[reply]
The problem with that is I am not using java. I am using C# and python 3.4.3. I am having to use python because it can run new code at run-time via the exec function. I don't think C# can do that. —SGA314 I am not available on weekends (talk) 19:15, 16 July 2015 (UTC)[reply]
Both Python and C# have SSL libraries.
It doesn't sound like you really care about confidentiality here. You care about integrity (only commands sent by someone who knows the secret should be run). If confidentiality doesn't matter then you don't need to encrypt the message in the first place. You just need to append a message authentication code.
I've never used .NET's crypto libraries, but it appears that you're only calling TransformBlock once, and therefore only encrypting/decrypting one block, regardless of the message size. That might explain the garbled output.
Padding the message with zeroes to a multiple of the block size is not going to work because it's not reversible (the message might end with a zero). You should use a standard padding scheme (PKCS#7 padding is probably the most common), or use a block cipher mode that doesn't require padding, such as CTR. Currently you're using CBC, the default, because you didn't set another one.
Fundamentally, though, if this is a system that actually matters to you, and not just a toy, stop trying to invent your own encryption. Use crypto_secretbox. You still need to ensure the sender never reuses a nonce, and the receiver rejects messages with a reused nonce (to prevent replay attacks), and you need to keep the shared secret secret. But NaCl will handle everything else for you. It's also much faster (per byte) than authenticated AES-CBC, if that matters to you.
If you use SSL instead, to get integrity you need to generate a certificate for the sender and ensure that the receiver validates it before accepting the data. You don't have to use a standard certificate authority; you could create your own certificate authority and add it to the receiver's trusted list. But I think this would be far more difficult than using NaCl, and easier to screw up leaving you with no real security. -- BenRG (talk) 22:33, 16 July 2015 (UTC)[reply]
Ok so what your saying is that it would be simpler and more secure to use SSL than to encrypt the data. If so, then how would I implement an SSL connection between 2 python or C# programs? As for using crypto_secretbox, I try to stay away from using external libraries because I don't have access to the source. Also, if I want ever want to sell or redistribute a program that I make that uses an external library, then I might run into licensing issues. Thus my reason for not using external libraries. Although I will use an external library is I absolutely need to. —SGA314 I am not available on weekends (talk) 17:09, 17 July 2015 (UTC)[reply]