As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
So after CodingHorror's fun with encryption and the thrashing comments, we are reconsidering doing our own encryption.
In this case, we need to pass some information that identifies a user to a 3rd party service which will then call back to a service on our website with the information plus a hash.
The 2nd service looks up info on that user and then passes it back to the 3rd party service.
We want to encrypt this user information going into the 3rd party service and decrypt it after it comes out. So it is not a long lived encryption.
On the coding horror article, Coda Hale recommended BouncyCastle and a high level abstraction in the library to do the encryption specific to a particular need.
My problem is that the BouncyCastle namespaces are huge and the documentation is non-existant. Can anyone point me to this high level abstraction library? (Or another option besides BouncyCastle?)
High level abstraction? I suppose the highest level abstractions in the Bouncy Castle library would include:
The BlockCipher interface (for symmetric ciphers)
The BufferedBlockCipher class
The AsymmetricBlockCipher interface
The BufferedAsymmetricBlockCipher class
The CipherParameters interface (for initializing the block ciphers and asymmetric block ciphers)
I am mostly familiar with the Java version of the library. Perhaps this code snippet will offer you a high enough abstraction for your purposes (example is using AES-256 encryption):
public byte[] encryptAES256(byte[] input, byte[] key) throws InvalidCipherTextException {
assert key.length == 32; // 32 bytes == 256 bits
CipherParameters cipherParameters = new KeyParameter(key);
/*
* A full list of BlockCiphers can be found at http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/BlockCipher.html
*/
BlockCipher blockCipher = new AESEngine();
/*
* Paddings available (http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/paddings/BlockCipherPadding.html):
* - ISO10126d2Padding
* - ISO7816d4Padding
* - PKCS7Padding
* - TBCPadding
* - X923Padding
* - ZeroBytePadding
*/
BlockCipherPadding blockCipherPadding = new ZeroBytePadding();
BufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding);
return encrypt(input, bufferedBlockCipher, cipherParameters);
}
public byte[] encrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException {
boolean forEncryption = true;
return process(input, bufferedBlockCipher, cipherParameters, forEncryption);
}
public byte[] decrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException {
boolean forEncryption = false;
return process(input, bufferedBlockCipher, cipherParameters, forEncryption);
}
public byte[] process(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters, boolean forEncryption) throws InvalidCipherTextException {
bufferedBlockCipher.init(forEncryption, cipherParameters);
int inputOffset = 0;
int inputLength = input.length;
int maximumOutputLength = bufferedBlockCipher.getOutputSize(inputLength);
byte[] output = new byte[maximumOutputLength];
int outputOffset = 0;
int outputLength = 0;
int bytesProcessed;
bytesProcessed = bufferedBlockCipher.processBytes(
input, inputOffset, inputLength,
output, outputOffset
);
outputOffset += bytesProcessed;
outputLength += bytesProcessed;
bytesProcessed = bufferedBlockCipher.doFinal(output, outputOffset);
outputOffset += bytesProcessed;
outputLength += bytesProcessed;
if (outputLength == output.length) {
return output;
} else {
byte[] truncatedOutput = new byte[outputLength];
System.arraycopy(
output, 0,
truncatedOutput, 0,
outputLength
);
return truncatedOutput;
}
}
Edit: Whoops, I just read the article you linked to. It sounds like he is talking about even higher level abstractions than I thought (e.g., "send a confidential message"). I am afraid I don't quite understand what he is getting at.
Assuming that you write your application in Java I'd recommend that you don't use a specific provider, but that you develop your application on top of Sun's JCE (Java Cryptography Extension). Doing so can make you independent of any underlying providers, I.e., you can switch providers easily as long as you use ciphers that are widely implemented. It does give you a certain level of abstraction as you don't have to know all the details of the implementations and may protect you a little from using the wrong classes (e.g. such as using raw encryption without proper padding etc) Furthermore, Sun provides a decent amount of documentation and code samples.
I've actually found that this sample uses default 128 bit encryption instead of 256 bit. I've made a little change:
BlockCipher blockCipher = new AESEngine();
now becomes:
BlockCipher blockCipher = new RijndaelEngine(256);
and it works together with my client application C++ AES256 encryption
One example of a high(er)-level API in BouncyCastle would be the CMS (Cryptographic Message Syntax) package. This ships in a separate jar (bcmail) from the provider itself, and is written to the JCE (The C# version is written against the lightweight API however).
"Send a confidential message" is implemented, roughly speaking, by the CMSEnvelopedDataGenerator class, and all you really need to do is give it the message, choose an encryption algorithm (all details handled internally), and then specify one or more ways that a recipient will be able to read the message: this can be based on a public key/certificate, a shared secret, a password, or even a key agreement protocol. You can have more than one recipient on a message, and you can mix and match types of recipient.
You can use CMSSignedDataGenerator to similarly send a verifiable message. If you want to sign and encrypt, the CMS structures are nestable/composable (but order could be important). There's also CMSCompressedDataGenerator and recently added CMSAuthenticatedData.
You may use:
byte[] process(bool encrypt, byte[] input, byte[] key)
{
var cipher = CipherUtilities.GetCipher("Blowfish");
cipher.Init(false, new KeyParameter(key));
return cipher.DoFinal(input);
}
// Encrypt:
byte[] encrypted = process(true, clear, key);
// Decrypt:
byte[] decrypted = process(false, encrypted, key);
See: https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs
JCE won't work for me because we want 256 bit strength and can't change the java configuration on the system to allow it. Too bad the Bouncy Castle doesn't have an API as high-level as JCE.
"Note however that bouncycastle consists of two libraries, the lightweight crypto library and the JCE provider interface library. The keysize restrictions are enforced by the JCE layer, but you don't need to use this layer. If you just use the lightweight crypto API directly you don't have any restrictions, no matter what policy files are or are not installed."
http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography
The book Beginning Cryptography with Java contains very helpful examples and explanations based on the bouncycastle library
Related
Proto3 release notes states:
The
deterministic serialization is, however, NOT canonical across languages; it
is also unstable across different builds with schema changes due to unknown
fields. Users who need canonical serialization, e.g. persistent storage in
a canonical form, fingerprinting, etc, should define their own
canonicalization specification and implement the serializer using reflection
APIs rather than relying on this API.
What I would like to achieve is to have a deterministic serialisation of protobuf message to carry a crypto signature along with it. As I understand due to differences in serialisers binary data could differ and signature would become invalid.
package Something
message Request {
Payload payload = 1;
// signature of serialised payload
bytes signature = 2;
message Payload {
string user_id_from = 1;
uint64 amount = 2;
string user_id_to = 3;
}
}
What is the way to do this using protobuf reflection?
This doesn't answer the question directly, but may solve your issue: don't store the payload as a message, but store the serialized bytes alongside with the signature.
message Request {
// Serialized Payload message.
bytes payload = 1;
// signature of serialised payload
bytes signature = 2;
}
message Payload {
string user_id_from = 1;
uint64 amount = 2;
string user_id_to = 3;
}
This may be a little less convenient to work with in code, but has the advantage of preserving all the forwards and backwards-compatibility guarantees of protobuf.
It also frees you from serializing the message twice when writing it (once as a subfield, once to get the signature).
as I'm a newbie in this field the question may seem to be so stupid, but please forgive me. I want to achieve SHA-512 in Objective-C for an equivalent Java code..Here is the Java Code :
String passwordSalt = "Somesalt";
byte[] bsalt=base64ToByte(passwordSalt);
byte[] passwordToDigestAsBytes=("somepassword").getBytes("UTF-8");
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.reset();
digest.update(bsalt);
byte[] = input digest.digest(passwordToDigestAsBytes);
I'm using CC_SHA512 for digest function...but what I need to do for digest.update(bsalt) part? how can I achieve the same functionality in Objective-C?
I'm not familiar with Java's MessageDigest object, but it looks like it's just prepending the salt before the data, which is a very normal way to process this kind of data. So you'd just call CC_SHA512_Update() twice. Once with the salt, and then a second time with the password data. Then you'd call CC_SHA512_Final() to fetch the result.
I am writing an encryption application that requires a 64 bit key. I am currently using the following code to automatically generate a key.
Function GenerateKey() As String
' Create an instance of a symmetric algorithm. The key and the IV are generated automatically.
Dim desCrypto As DESCryptoServiceProvider = DESCryptoServiceProvider.Create()
' Use the automatically generated key for encryption.
Return ASCIIEncoding.ASCII.GetString(desCrypto.Key)
End Function
I am wanting the user to create their own key. Can I convert a user defined password (a string) into a 64 bit key that can be used?
The answer depends on how secure you want it to be, I'm no security expert so I wouldn't give advice on it.
I did see this though: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx It can be used to derives bytes from a string key and salt in the way Jodrell eluded to, and would be far better than rolling yor own.
The other constructor that might be suited after that stage is detailed here: http://msdn.microsoft.com/en-us/library/51cy2e75.aspx
I'm sure if you searched for that on the web you could find examples of how to use it.
I have seen people using UUID for authentication token generation. However, in RFC 4122 it is stated that
Do not assume that UUIDs are hard to guess; they should not be used
as security capabilities (identifiers whose mere possession grants
access), for example.
I was wondering, what algorithms are used for example in Java and .NET for SessionId/AuthenticationToken generation. Is UUID indeed unsuitable for these purposes in an application that has more than average security needs?
UUID generation is random, but random with bad entropy means that you will end up with easy to guess UUIDs. If you use a good random number generator, you can generate UUIDs that can be used for sessions. The catch to this, however, is that UUIDs don't have built-in re-play prevention, tampering, fixation, etc., you have to handle that on your own (read: a UUID by itself shouldn't be considered a valid session ID by itself). That said, here's a good snippet for how you would generate a secure UUID using python:
Unique session id in python
Disclaimer: I am not a cryptographer.
Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example.
While in general that is true, it should also be noted that some systems produce UUIDs using cryptographically strong pseudo random number generators (e.g. Java):
public static UUID randomUUID()
Static factory to retrieve a type 4 (pseudo randomly generated) UUID. The UUID is generated using a cryptographically strong pseudo random number generator.
Returns:
A randomly generated UUID
I was wondering, what algorithms are used for example in Java and .NET for SessionId/AuthenticationToken generation.
Tomcat does not use UUIDs as session tokens but uses a SHA1PRNG secure random generator for producing session IDs:
/**
* The name of the algorithm to use to create instances of
* {#link SecureRandom} which are used to generate session IDs. If no
* algorithm is specified, SHA1PRNG is used. To use the platform default
* (which may be SHA1PRNG), specify the empty string. If an invalid
* algorithm and/or provider is specified the {#link SecureRandom} instances
* will be created using the defaults. If that fails, the {#link
* SecureRandom} instances will be created using platform defaults.
*/
private String secureRandomAlgorithm = "SHA1PRNG";
This is just the default and you can provide your custom session ID generator by implementing the org.apache.catalina.SessionIdGenerator interface.
Other than using a randomly generated string in the session ID, the standard implementation also adds a jvmRoute to the session IDs that it generates:
A routing identifier for this Tomcat instance. It will be added to the session id to allow for stateless stickyness routing by load balancers. The details on how the jvmRoute will be included in the id are implementation dependent. See Standard Implementation for the default behavior.
Strength of SHA1PRNG has already been discussed here.
Is UUID indeed unsuitable for these purposes in an application that has more than average security needs?
Java UUIDs are almost as secure as Tomcat's default session ID generator which generates 16 byte long session IDs:
Tomcat:
/** Number of bytes in a session ID. Defaults to 16. */
private int sessionIdLength = 16;
java.util.UUID in OpenJDK 7:
public static UUID randomUUID() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
But you can configure Tomcat's session ID generator to use more than 16 bytes for added security.
Further reading:
https://security.stackexchange.com/a/7945/122069
I am trying to create a serial number checker in an app that I am writing, and it uses cryptography to encode the name and entered number against what it actually should be. I am familiar with the SHA1CryptoServiceProvider used in C#, but is there anything like this in Objective-C?
Here is sample code from C# that I want to convert to Objective-C:
string license = txtnLicense.Text;
SHA1CryptoServiceProvider provider = new SHA1CryptoServiceProvider();
string finalLicense = BitConverter.ToString(provider.ComputeHash(bytes));
bool isGood = (BitConverter.ToString(provider.ComputeHash(bytes)).Replace("-", "") == license.Replace("-", ""));
Mac OS X comes with an easy-to-use encryption and hashing library built-in called CommonCrypto. You don't have to link against anything special to use it. See the headers in /usr/include/CommonCrypto for its interface and CC_SHA1(3cc) for docs.
using openssl for license keys shows how to use SHA1. It may be a good start.