Terraform - SHA256 hash of bytes that have been base64-encoded - hash

Let's say that I have three null bytes, and I base64-encode them:
(Python)
import base64
import hashlib
foo = b'\xd3\x4d\x34'
foo_b64 = base64.b64encode(foo)
print(foo_b64)
# Outputs:
# 0000
foo_sha256 = hashlib.sha256(foo).hexdigest()
print(foo_sha256)
# Outputs:
# 0e10e03565f4664a05c3bc63ed35df3e1a9cb2568371db4f12b66c728943f802
Let's say I put that base64 string in a Terraform config:
locals {
foo_b64 = "0000"
}
In Terraform, I need to find a way to get the SHA256 hash of the raw value of foo, i.e. in Terraform I need to generate that same hash (0e10e03565f4664a05c3bc63ed35df3e1a9cb2568371db4f12b66c728943f802).
I've gone through the Terraform functions and can't seem to find something that works.
sha256(local.foo_b64) gives the SHA256 hash of the base64 string, not the raw bytes that it encodes.
sha256(base64decode(local.foo_b64)) throws an error: Call to function "base64decode" failed: the result of decoding the provided string is not valid UTF-8.
Is there any way to achieve this?

The Terraform language has a string type that is defined as containing Unicode characters rather than bytes, so anything which creates a string from raw input requires that input to be UTF-8 encoded Unicode characters.
This means that it isn't possible in general to pass raw binary data from one function to another. For situations where a Terraform configuration does need to work with small binary objects, the convention is to pass them around as base64 encoding, but that works only if your configuration treats the base64 data as opaque, never needing to decode it, because there is no way to represent the decoded form.
Given that, I think in order to solve your underlying problem with Terraform you will need to take a different approach. For example, perhaps whatever external system is generating the base64 string could also generate the SHA256 checksum of it, which Terraform would then also treat as opaque rather than trying to calculate it directly. You've presented one technical solution to an unstated problem here, so I can't be any more specific about what other options might be, but the main requirement would be that Terraform will just pass through the (base64-encoded) binary data verbatim to a provider and never interrogate it directly itself.

Related

Is there a default label for the built-in RSA-OAEP encryption in Java?

I am implementing my own version of RSA-OAEP with SHA-256. I want to test it by comparing it to the output of the Cipher class in Java using RSA-OAEP and SHA-256. According to PKCS #1, RSA-OAEP requires a label, which by default is an empty string. However, I can't find a way to input a label in the built-in class. My implementation seems to work correctly for both encryption and decryption, but Cipher class produces different output. Is there a default label which the Cipher class uses?
What is called label L in PKCS1v2.1 RSAES-OAEP was called encoding parameters P in v2.0; see the description of pSourceAlgorithm in A.2.1. The Java API keeps the old terminology, presumably for compatibility, and the default is indeed an empty octet string, implemented in Java as a byte array of length 0. See https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/PSource.PSpecified.html . Note that even when P-call-me-L is empty, its hash which goes in DB before masking is not empty.
When you say 'different output', you do realize that OAEP is randomized (in a way that provably does not leak information to the adversary) and every encryption of the same plaintext should produce a unique ciphertext, but all of them should decrypt back to the same plaintext, right?

Perl HTTP Request content() issue

I want to put a file (file.img) as a POST data content, so if the file is in the same folder as the script, is $req->content(file.img); valid ?
Cheers
This seems to be something that you could easily test for yourself rather than asking us. What happened when you tried it?
(I'm going to assume that $req is an HTTP::Request object - I don't know why you wouldn't include that information in your question).
In short, no, it's not valid. And it's not valid for a number of reasons.
It's not valid because file.img would be interpreted as the bareword file concatenated with the bareword img - which would give the string fileimg.
It's not valid because use strict makes barewords illegal, so if you're using use strict (and you really should be) your code won't even compile.
It's not valid because HTTP::Request::content expects a sequence of bytes. So even if you didn't use use strict all this code would do would be to add the string fileimg to the request body.
If you want to add the contents of the file to the body, then you need to open the file, read in the data and then pass that data to content.
This is all explained in the documentation for HTTP::Request.

Converting a String to a Splittable in GWT

I'm maintaining a site written in GWT (2.5.0) that is used internally by our development team, and I've been experimenting with using AutoBeans for client side json parsing. I have a few objects with json that is not well defined — a developer can dump whatever json string he wants in there — so I'm using a Splittable property. In order to support editing this arbitrary json I'd like to convert a String into a Splittable, but I haven't found a straight-forward way of accomplishing this. Do I need to implement this interface myself or resort to something hacky like wrapping the json in another json object I can then decode into a throw-away AutoBean just to get a Splittable of the original json?
StringQuoter is the utility class which we do much of our manual Splittable work with.
Just user StringQuoter.create("some string"); to produce a Splittable whose payload is
"some string"
Once you have that splittable, you can assign it to a key in another splittable with the following method:
Splittable.assign(Splittable parent, String propertyName);
However, if you are trying to convert some arbitrary string which contains a JSON structure into a splittable, use StringQuoter.split(..) to create it. The resulting splittable can be queried as normal (i.e. what keys exist/don't exist, etc).

using protobuf as a textual configuraton file

I recently encountered a very large mission-critical project where all the configuration
files were defined using textual protobuf definitions. The configuration files are meant to be
human readable and editable.
For example
message ServerSettings {
required int32 port = 3022;
optional string name = "mywebserver";
}
Personally I found this humorous.
But is it in fact a reasonable keep-it-simple technique, or clearly moronic ?!
In other words, are there REAL, ACTUAL problems with this ?
If that is the text proto if format, then... Whatever, I guess. If it works, then it is as reasonable as any other serialization format.
If that is meant to be proto schema, then it is illegal (the value after the = is meant to be the field number).
Json or XML might be more typical, but as long as it works it isn't "moronic". So the ultimate question is: does it work?
I think it's quite clever. I am guessing they pass it through protoc --encode to generate a binary which is what is actually parsed.
Pros:
1. Code is generated to parse configuration
2. Type validation
3. More robust configuration file compared to a key/value as it supports structs, unions, maps and arrays
4. The configuration data is now serializable meaning it can be easily exposed to an RPC or IPC interface.
Cons:
1. The syntax can be a little verbose for maps/arrays.
2. It requires protoc to be installed on the target as well as libprotobuf.so if you are on a system with tight memory limits.

How to hash in CFMX_COMPAT in c#

An existing coldfusion website is to be converted to dot net.
In the coldfusion code, the password is hashed using its hash() function with no algorithm:
SomePassword = '#hash(fldPassword)#'
I found this document, saying the default encryption is
CFMX_COMPAT: Generates a hash string identical to that generated by
ColdFusion MX and ColdFusion MX 6.1 (default).
There are some articles actually telling me how to decrypt.
According to Macromedia, The ColdFusion Encrypt function uses an
XOR-based algorithm that utilizes a pseudo random 32-bit key based on
a seed passed by the user as a parameter to the function. The
resulting data is UUencoded.
You'll need to uudecode the encoded value first
http://www.eggheadcafe.com/printsear...asp?linkid=351
and then XOR it using the key it was encrypted with.
http://www.java2s.com/Code/CSharp/La...deamessage.htm
If you dont have the key - your wasting yuor time.
But, how to make it work? I don't think there is any key. All I can see is '#hash(fldPassword)#'. Please help. Thanks.
There are some articles actually telling me how to decrypt.
Hashing and encryption are not the same thing. Encryption can be reversed. You can recover the original value if you have the right key, etectera. Whereas hashing is a one way trip. Once hashed, the original value cannot be recovered. (Well .. in theory. Some of the weaker hashing algorithms have been broken.) So you cannot "decrypt" a hashed value. But you can duplicate the obfuscated result string.
I found this document, saying the default encryption is CFMX_COMPAT
Actually it refers to the default algorithm. However, I am not so sure that description is correct. (Edit: As Rasmus correctly points out, it does say the default is MD5) However, CF9/7 default to MD5 anyway. Even when the algorithm is CFMX_COMPAT. So in either case, a simple MD5 hash in C# would give you the same result.
ie These all produce identical results ie 098F6BCD4621D373CADE4E832627B4F6.
#hash("test")#
#hash("test", "cfmx_compat")#
#hash("test", "md5")#
If I read the documentation correctly, CFMX_COMPAT hashing is just MD5.
So:
byte[] hash = MD5.Create().ComputeHash(fldPassword);
It should be easy to verify if you have access to a ColdFusion installation.