Public key encoding changes - encoding

I've generated a public key using elliptic curves, but whenever I get the encoding of the key, it changes. I would like to use the encoding for a public address of a blockchain I am implementing. See below
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
class Scratch {
public static void main(String[] args) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
keyGen.initialize(ecSpec);
KeyPair kp = keyGen.generateKeyPair();
PublicKey k = kp.getPublic();
byte[] one = k.getEncoded();
byte[] two = k.getEncoded();
System.out.println(one);
System.out.println(two);
}
}
With output
[B#4eec7777
[B#3b07d329
Does anyone know why this is happening? My guess is that it is the expected behavior and I am just misunderstanding something fundamental here.

You are printing the memory address of the byte[], not the key itself. You can't "print" a byte array because it is binary data, you need to encode it somehow first. Hex and base64 are both good encodings for displaying binary data. For memory, other blockchain implementations like to use base58.
Here is an example using base64:
String b64Str = Base64.getEncoder().encodeToString(one);
System.out.println(b64Str);

Related

Kafka producing message key as STRING even though the REST program has INT?

I am using following program to produce records in kafka:
import java.io.IOException;
import java.security.SecureRandom;
public class SensorStatusProducer {
private final static String TOPIC = "SENSOR_STATUS_DETAILS";
private final static String PRODUCER_URI = "http://xxx.xxx.xxx.xxx:8082/topics/" + TOPIC;
private final static SecureRandom randomNumber = new SecureRandom();
private final static SensorDetails sensorDetails = new SensorDetails();
public static void main(String[] args) {
int[] sensorid = sensorDetails.getSensorid(); //this will return [1001,1002,1003,1004,1005]
try {
HttpRestProxyUtil rest = new HttpRestProxyUtil(); //this is defined in another class
for (int sid : sensorid) {
rest.produceRecords(PRODUCER_URI, String.format("{\"records\":[{\"key\": %d," +
"\"value\":{" +
"\"sensorid\":%d," +
"\"status\":%s," +
"\"lastconnectedtime\":%s}}]}", sid, sid, "\"CONNECTED\"", String.format("\"%s\"", sensorDetails.currentTimestamp()))); //currentTimestamp() function in defined in another class
}
} catch (InterruptedException | IOException me) {
me.printStackTrace();
}
}
}
The key has format specifier as %d but the record produced has key of STRING type.
This is evident by following:
When trying to make table:
CREATE TABLE STATUS_IB_TABLE (ROWKEY INT KEY,
sensorid INTEGER,
status VARCHAR,
lastconnectedtime STRING)
WITH (TIMESTAMP='lastconnectedtime', TIMESTAMP_FORMAT='yyyy-MM-dd HH:mm:ss', KAFKA_TOPIC='SENSOR_STATUS_DETAILS', VALUE_FORMAT='JSON', KEY='sensorid');
The KEY is serialized as STRING as pointed out by #Andrew Coates
I don't know how's that possible.
can someone please clarify this for me, what am I doing wrong?
PS:
=> this is a follow up question for my earlier question ksqlDB not taking rowkey properly
=> Confluent Platform version: 5.5
=> This is the main class of the program.
The REST Proxy supports various content types, but not including the primitive type to write a serialized 32-bit integer.
Your code is thus producing data to the topic with a string key. For an example of how to produce an INT see the example here which uses kafkacat.
Since you're using Java, you could use the native Java Producer API to control exactly how the data is produced to Kafka (which is also more performant and flexible than the REST API).

INET Nordic FIX protocols extending to nanosecond granularity timestamps

All INET Nordic FIX protocols will be enhanced by extending to nanosecond granularity timestamps on 16.oktober 2015 (see notification and section 3.1.1 in the spec).
The timestamps will look like this: 20150924-10:35:20.840117690
quickfix currently rejects messages that contain fields with this new format with the error: Incorrect data format for value
Are there any plans to support this new format? Or maybe some workaround?
You can first try modifying your data dictionary. For example if you are using fix42.xml that comes with QuickFIX, you can change the affected timestamp fields from type='UTCTIMESTAMP' to type='STRING'.
If that isn't enough, you should instead write a patch against QuickFIX in C++, which should be somewhat straightforward once you know where to patch it, which I think is UtcTimeStampConvertor, around here: https://github.com/quickfix/quickfix/blob/master/src/C%2B%2B/FieldConvertors.h#L564
I think you need to add a case 27: above case 21: near the top, because your format has six extra digits. It looks like the rest of the function doesn't care about the total field length.
Of course if you want to actually inspect the sub-millisecond precision part of these timestamps, you'll need to do more.
No plans in QF/n, but only because this is the first I've heard of this.
I'll need to write some tests to see what the repercussions are. It may be that the time/date parser just truncates the extra nano places when it converts the string to a DateTime.
I've opened an issue: https://github.com/connamara/quickfixn/issues/352
This change is as far as I know kind of breaking the fix protocol definition of timestamps but that's another story.
There is a static class in QuickFixn called DateTimeConverter under QuickFix/Fields/Converters.
To get this to work correctly you would need to add format strings in lines in that class.
Add "yyyyMMdd-HH:mm:ss.fffffff" to DATE_TIME_FORMATS and "HH:mm:ss.fffffff" to TIME_ONLY_FORMATS so that it would look like this.
/// <summary>
/// Convert DateTime to/from String
/// </summary>
public static class DateTimeConverter
{
public const string DATE_TIME_FORMAT_WITH_MILLISECONDS = "{0:yyyyMMdd-HH:mm:ss.fff}";
public const string DATE_TIME_FORMAT_WITHOUT_MILLISECONDS = "{0:yyyyMMdd-HH:mm:ss}";
public const string DATE_ONLY_FORMAT = "{0:yyyyMMdd}";
public const string TIME_ONLY_FORMAT_WITH_MILLISECONDS = "{0:HH:mm:ss.fff}";
public const string TIME_ONLY_FORMAT_WITHOUT_MILLISECONDS = "{0:HH:mm:ss}";
public static string[] DATE_TIME_FORMATS = { "yyyyMMdd-HH:mm:ss.fffffff", "yyyyMMdd-HH:mm:ss.fff", "yyyyMMdd-HH:mm:ss" };
public static string[] DATE_ONLY_FORMATS = { "yyyyMMdd" };
public static string[] TIME_ONLY_FORMATS = { "HH:mm:ss.fffffff", "HH:mm:ss.fff", "HH:mm:ss" };
public static DateTimeStyles DATE_TIME_STYLES = DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal;
public static CultureInfo DATE_TIME_CULTURE_INFO = CultureInfo.InvariantCulture;

Browser replaces '+ ' character with space

I am passing an attribute(say, test="ae23+raj") in URL and retrieve it. My URL is 10.203.16.15:8080/page1?test="ae23+raj"
I initially thought this is related to encoding issue and tried out that option too. Later i noticed that after retrieving the attribute value, I printed the value in Window.alert(test). i get "ae23 raj" as value.
I need this value as it's. That is "ae23+raj". I don't know how many such special characters are there which will be replaced by the browser with some other character. Any help here? Thanks in advance.
Encode/Decode the URL. Here are the JSNI methods that you can use at client side.
public static final native String encodeUri(String uri) /*-{
return encodeURI(uri);
}-*/;
public static final native String decodeUri(String uri) /*-{
return decodeURI(uri);
}-*/;
%22ae23%2Braj%22 is the encoded value of "ae23+raj". Decode back at client side to get the desired value.
There are lots of others ways also in JavaScript to encode/decode the URL.
Read about
JavaScript decodeURI() Function
JavaScript decodeURIComponent() Function
JavaScript encodeURI() Function
JavaScript encodeURIComponent() Function
Look at URL Decoder/Encoder.
Read more about HttpServletResponse#encodeURL() to encode a URL at server side.
how to get url query params
/** The query params. */
private static Map<String, String> queryParams = new HashMap<String, String>();
static {
Map<String, List<String>> paramsMap = Window.Location.getParameterMap();
for (String key : paramsMap.keySet()) {
List<String> values = paramsMap.get(key);
if (values.size() > 0) {
String value = decodeUri(values.get(0));
queryParams.put(key.toLowerCase(), value);
queryParams.put(key, value);
}
}
}
In a query-string encoded as application/x-www-form-urlencoded (what most people use: key-value pairs separated by & with a = as the key-value separator), a + is the encoded value of a space: http://www.w3.org/TR/html5/forms.html#url-encoded-form-data.
You have to use %20 for a space.
…or you could deviate from the de-facto standard, but then you'll have to parse your query-string yourself, as all tools (HttpServlerRequest#getParameter and GWT's Window.Location#getParameter, to name a few) will decode the + into a space.

IOS: Decrypting a message with public key received from webservice

I'm new to this topic so sorry if this is a stupid question :\
I'm trying to decrypt a message with a given public key. Both the message and public key is given from the webservice.
See the following code for how i currently do the decrypting:
for (NSValue *refVal in keyRefs) {
SecKeyRef p_key = NULL;
[refVal getValue:&p_key];
if (p_key == NULL) continue;
size_t dataLength = encryptedData.length;
size_t outPutLength = MAX(dataLength, SecKeyGetBlockSize(p_key));
void *outPutBuf = malloc(outPutLength);
if (outPutBuf) {
// Error handling
OSStatus status = SecKeyDecrypt(p_key,
kSecPaddingNone,
encryptedData.bytes,
encryptedData.length,
outPutBuf,
&outPutLength
);
NSLog(#"decryption result code: %ld (size: %lu)", status, outPutLength);
NSLog(#"FINAL decrypted text: %s", outPutBuf);
if (status == errSecSuccess) {
break;
}
} else {
//Error handling
}
}
I get no errors, but the decrypted string is displayed like this (the correct output should be a JSON array):
decryption result code: 0 size:511)
FINAL decrypted text: ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ
Is it because I use the "SecKeyDecrypt" with a "public key" instead of a "private key"? In that case, what should i instead use for decrypting?
Thanks for any help regarding this!
EDIT: I'm using code from: http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/ to use the public key i get from the server (this is where "keyRefs" from the code snippet comes from)
Of course, the public key is something someone else uses to encrypt data so that only someone with the private key can decrypt it.
The very definition of a public key is that you can give it to anyone. You wouldn't want anyone to be able to decrypt anyone else's encrypted message would you?
It is impossible to tell from your code fragment where your private key is stored, or what the contents (or even class) of keyRefs is.
EDIT: In response to above OP's comment. And clarification.
*"The public key itself is the public part of a RSA-key-pair stored on the server. The encrypted message was created on the server by first JSON-encoding the object, then encrypted with the private-key with OPENSSL_PKCS1_PADDING, then base64-encoded, and then JSON-encoded again as a part of the final message. The message and public key is stored on the client. What i want is to decrypt the message on the client by using the public key. As i said, im not very good at this subject so i might have tried to do this the wrong way"*
Thats not how public key cryptography works. The server and client exchange public keys. Then each of them use the other's public key to encrypt data sent to the opposite party. The receiving party always uses their own private key to decrypt the message.
If you want the server to generate an encrypted response, have the client pass their public key in the request, use that public key to encrypt the response, and then decrypt the response on the client with the client's private key.

Why is Jersey's UriBuilder.build method encoding #'s and %'s, but not /'s?

I have a REST API which is fairly typical, except that the id's of resources are not integers, but strings, which often contain / characters. So if a customer's id is string/with/slashes then the URI for that customer should be http://localhost/customers/string%2Fwith%2Fslashes. When returning a list of customers, I want to construct that URI with a UriBuilder so I can put it in the href of ATOM-style link elements. But it doesn't quite work; here's a small test class that shows what I mean:
#Path("/customers")
public class JerseyTest {
#Path("{id}")
public Customer getCustomer(#PathParam("{id}") String id) {
return null;
}
public static void main(String[] args) {
buildURI("string#with#hashes"); // => http://localhost/customers/string%23with%23hashes
buildURI("string/with/slashes"); // => http://localhost/customers/string/with/slashes
}
public static void buildURI(String id) {
UriBuilder builder = UriBuilder.fromUri("http://localhost");
builder.path(JerseyTest.class).path(JerseyTest.class, "getCustomer");
URI uri = builder.build(id);
System.out.println(uri);
}
}
The #'s get encoded as I would expect but the /'s don't. I tried using builder.build(URLEncoder.encode(id)) instead, but then the UriBuilder encodes the %'s so you get .../string%252Fwith%252Fslashes!
It seems inconsistent to me that it encodes # and % but not /, but I suspect there is a good reason for it which I am not seeing. So my question is:
How can I get UriBuilder to give me .../string%2Fwith%2Fslashes, which is the URI that causes Jersey to call getCustomer with id equal to string/with/slashes? edit: I discovered a way to solve this: builder.buildFromEncoded(URLEncoder.encode(id)). Leaving this question open though, in hopes of getting an answer to the second part...
More generally, why does UriBuilder.build encode some special characters, but not others?
I found How do I encode URI parameter values?, where the accepted answer says "Use UriBuilder." Well, I am using it, but apparently I'm using it incorrectly.
This seem to be a confirmed issue:
http://java.net/jira/browse/JAX_RS_SPEC-70
Your workaround sounds good.