I create following singleton class to encrypt and decrypt the string messages.
public class EncryptionHelper {
private Cipher ecipher;
private Cipher dcipher;
private SecretKey key;
private byte iv[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
private static EncryptionHelper instance;
public static EncryptionHelper getInstance( String defKey ) {
synchronized( EncryptionHelper.class ) {
if ( null == instance ) {
try {
instance = new EncryptionHelper( defKey );
} catch( Exception e ) {
}
}
}
return instance;
}
private EncryptionHelper( String defKey )
throws Exception {
DESedeKeySpec keyspec = new DESedeKeySpec( defKey.getBytes() );
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "TripleDES" );
key = keyfactory.generateSecret( keyspec );
ecipher = Cipher.getInstance( "TripleDES/CBC/PKCS5Padding" );
dcipher = Cipher.getInstance( "TripleDES/CBC/PKCS5Padding" );
ecipher.init( Cipher.ENCRYPT_MODE, key, new IvParameterSpec( iv ) );
dcipher.init( Cipher.DECRYPT_MODE, key, new IvParameterSpec( iv ) );
}
public String encrypt( String str ) {
try {
byte[] utf8 = str.getBytes( "UTF-8" );
byte[] enc = ecipher.doFinal( utf8 );
String val = Base64.getEncoder().encodeToString( enc );
return val;
} catch( UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e ) {
}
return str;
}
public String decrypt( String str ) {
try {
byte[] dec = Base64.getDecoder().decode( str );
byte[] utf8 = dcipher.doFinal( dec );
return new String( utf8, "UTF8" );
} catch( IllegalBlockSizeException | BadPaddingException | IOException e ) {
}
return str;
}
}
When I tried to use encrypt and decrypt method of this class using two different program with different key as follows.
public static void main( String[] args ) {
EncryptionHelper encryptionHelper = EncryptionHelper.getInstance( "000000000000ffffffffffff" );
System.out.println( encryptionHelper.encrypt( "ABCDEFGH" ) );
}
Output is ::: n+0SEJQDXwfvpdMIdetNow==
and
public static void main( String[] args ) {
// Use different key to decrypt
EncryptionHelper encryptionHelper = EncryptionHelper.getInstance( "111111111111ffffffffffff" );
// Use output of previous call as input to decrypt
System.out.println( encryptionHelper.decrypt( "n+0SEJQDXwfvpdMIdetNow==" ) );
}
Output is ::: ABCDEFGH
As you can see I am using different keys while using encrypt and decrypt method but still the program is able to decrypt the exact value using wrong key.
Can you guys help me to know, why it is behaving like this, why I am able to decrypt using wrong key?
why I am able to decrypt using wrong key?
... because you are not using the second key, but the key that was used with the first call to getInstance
if you don't see that, answer the following question to yourself ... on your SECOND call to getInstance, when instance has already a value and is not NULL, how does defKey influence the instance? (hint: it doesn't)
Related
Folks,
I am trying to move data to s3 from Salesforce using apex class. I have been told by the data manager to send the data in zip/gzip format to the S3 bucket for storage cost savings.
I have simply tried to do a request.setCompressed(true); as I've read it compresses the body before sending it to the endpoint. Code below:
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:'+DATA_NAMED_CRED+'/'+URL+'/'+generateUniqueTimeStampforSuffix());
request.setMethod('PUT');
request.setBody(JSON.serialize(data));
request.setCompressed(true);
request.setHeader('Content-Type','application/json');
But no matter what I always receive this:
<Error><Code>XAmzContentSHA256Mismatch</Code><Message>The provided 'x-amz-content-sha256' header does not match what was computed.</Message><ClientComputedContentSHA256>fd31b2b9115ef77e8076b896cb336d21d8f66947210ffcc9c4d1971b2be3bbbc</ClientComputedContentSHA256><S3ComputedContentSHA256>1e7f2115e60132afed9e61132aa41c3224c6e305ad9f820e6893364d7257ab8d</S3ComputedContentSHA256>
I have tried multiple headers too, like setting the content type to gzip/zip, etc.
Any pointers in the right direction would be appreciated.
I had a good amount of headaches attempting to do a similar thing. I feel your pain.
The following code has worked for us using lambda functions; you can try modifying it and see what happens.
public class AwsApiGateway {
// Things we need to know about the service. Set these values in init()
String host, payloadSha256;
String resource;
String service = 'execute-api';
String region;
public Url endpoint;
String accessKey;
String stage;
string secretKey;
HttpMethod method = HttpMethod.XGET;
// Remember to set "payload" here if you need to specify a body
// payload = Blob.valueOf('some-text-i-want-to-send');
// This method helps prevent leaking secret key,
// as it is never serialized
// Url endpoint;
// HttpMethod method;
Blob payload;
// Not used externally, so we hide these values
Blob signingKey;
DateTime requestTime;
Map<String, String> queryParams = new map<string,string>(), headerParams = new map<string,string>();
void init(){
if (payload == null) payload = Blob.valueOf('');
requestTime = DateTime.now();
createSigningKey(secretKey);
}
public AwsApiGateway(String resource){
this.stage = AWS_LAMBDA_STAGE
this.resource = '/' + stage + '/' + resource;
this.region = AWS_REGION;
this.endpoint = new Url(AWS_ENDPOINT);
this.accessKey = AWS_ACCESS_KEY;
this.secretKey = AWS_SECRET_KEY;
}
// Make sure we can't misspell methods
public enum HttpMethod { XGET, XPUT, XHEAD, XOPTIONS, XDELETE, XPOST }
public void setMethod (HttpMethod method){
this.method = method;
}
public void setPayload (string payload){
this.payload = Blob.valueOf(payload);
}
// Add a header
public void setHeader(String key, String value) {
headerParams.put(key.toLowerCase(), value);
}
// Add a query param
public void setQueryParam(String key, String value) {
queryParams.put(key.toLowerCase(), uriEncode(value));
}
// Create a canonical query string (used during signing)
String createCanonicalQueryString() {
String[] results = new String[0], keys = new List<String>(queryParams.keySet());
keys.sort();
for(String key: keys) {
results.add(key+'='+queryParams.get(key));
}
return String.join(results, '&');
}
// Create the canonical headers (used for signing)
String createCanonicalHeaders(String[] keys) {
keys.addAll(headerParams.keySet());
keys.sort();
String[] results = new String[0];
for(String key: keys) {
results.add(key+':'+headerParams.get(key));
}
return String.join(results, '\n')+'\n';
}
// Create the entire canonical request
String createCanonicalRequest(String[] headerKeys) {
return String.join(
new String[] {
method.name().removeStart('X'), // METHOD
new Url(endPoint, resource).getPath(), // RESOURCE
createCanonicalQueryString(), // CANONICAL QUERY STRING
createCanonicalHeaders(headerKeys), // CANONICAL HEADERS
String.join(headerKeys, ';'), // SIGNED HEADERS
payloadSha256 // SHA256 PAYLOAD
},
'\n'
);
}
// We have to replace ~ and " " correctly, or we'll break AWS on those two characters
string uriEncode(String value) {
return value==null? null: EncodingUtil.urlEncode(value, 'utf-8').replaceAll('%7E','~').replaceAll('\\+','%20');
}
// Create the entire string to sign
String createStringToSign(String[] signedHeaders) {
String result = createCanonicalRequest(signedHeaders);
return String.join(
new String[] {
'AWS4-HMAC-SHA256',
headerParams.get('date'),
String.join(new String[] { requestTime.formatGMT('yyyyMMdd'), region, service, 'aws4_request' },'/'),
EncodingUtil.convertToHex(Crypto.generateDigest('sha256', Blob.valueof(result)))
},
'\n'
);
}
// Create our signing key
void createSigningKey(String secretKey) {
signingKey = Crypto.generateMac('hmacSHA256', Blob.valueOf('aws4_request'),
Crypto.generateMac('hmacSHA256', Blob.valueOf(service),
Crypto.generateMac('hmacSHA256', Blob.valueOf(region),
Crypto.generateMac('hmacSHA256', Blob.valueOf(requestTime.formatGMT('yyyyMMdd')), Blob.valueOf('AWS4'+secretKey))
)
)
);
}
// Create all of the bits and pieces using all utility functions above
public HttpRequest createRequest() {
init();
payloadSha256 = EncodingUtil.convertToHex(Crypto.generateDigest('sha-256', payload));
setHeader('date', requestTime.formatGMT('yyyyMMdd\'T\'HHmmss\'Z\''));
if(host == null) {
host = endpoint.getHost();
}
setHeader('host', host);
HttpRequest request = new HttpRequest();
request.setMethod(method.name().removeStart('X'));
if(payload.size() > 0) {
setHeader('Content-Length', String.valueOf(payload.size()));
request.setBodyAsBlob(payload);
}
String finalEndpoint = new Url(endpoint, resource).toExternalForm(),
queryString = createCanonicalQueryString();
if(queryString != '') {
finalEndpoint += '?'+queryString;
}
request.setEndpoint(finalEndpoint);
for(String key: headerParams.keySet()) {
request.setHeader(key, headerParams.get(key));
}
String[] headerKeys = new String[0];
String stringToSign = createStringToSign(headerKeys);
request.setHeader(
'Authorization',
String.format(
'AWS4-HMAC-SHA256 Credential={0}, SignedHeaders={1},Signature={2}',
new String[] {
String.join(new String[] { accessKey, requestTime.formatGMT('yyyyMMdd'), region, service, 'aws4_request' },'/'),
String.join(headerKeys,';'), EncodingUtil.convertToHex(Crypto.generateMac('hmacSHA256', Blob.valueOf(stringToSign), signingKey))}
));
system.debug(json.serializePretty(request.getEndpoint()));
return request;
}
// Actually perform the request, and throw exception if response code is not valid
public HttpResponse sendRequest(Set<Integer> validCodes) {
HttpResponse response = new Http().send(createRequest());
if(!validCodes.contains(response.getStatusCode())) {
system.debug(json.deserializeUntyped(response.getBody()));
}
return response;
}
// Same as above, but assume that only 200 is valid
// This method exists because most of the time, 200 is what we expect
public HttpResponse sendRequest() {
return sendRequest(new Set<Integer> { 200 });
}
// TEST METHODS
public static string getEndpoint(string attribute){
AwsApiGateway api = new AwsApiGateway(attribute);
return api.createRequest().getEndpoint();
}
public static string getEndpoint(string attribute, map<string, string> params){
AwsApiGateway api = new AwsApiGateway(attribute);
for (string key: params.keySet()){
api.setQueryParam(key, params.get(key));
}
return api.createRequest().getEndpoint();
}
public class EndpointConfig {
string resource;
string attribute;
list<object> items;
map<string,string> params;
public EndpointConfig(string resource, string attribute, list<object> items){
this.items = items;
this.resource = resource;
this.attribute = attribute;
}
public EndpointConfig setQueryParams(map<string,string> parameters){
params = parameters;
return this;
}
public string endpoint(){
if (params == null){
return getEndpoint(resource);
} else return getEndpoint(resource + '/' + attribute, params);
}
public SingleRequestMock mockResponse(){
return new SingleRequestMock(200, 'OK', json.serialize(items), null);
}
}
}
I'm using Pkcs#11 with the NCryptoki dll to use our HSM and manage the keys.
Why is this code giving me, sometimes, the error 145 (CKR_OPERATION_NOT_INITIALIZED)? I'm trying to avoid it, but I am still missing something... This error happens randomly when calling the session.Encrypt().
static public byte[] Crypto(Key key, byte[] input, bool encrypt, Mechanism mech, string command)
{
//Session session = openSession();
var tupla = openSessionTupla();
var session = tupla.Item1;
try
{
Utility.Logger("Crypto encrypt " + encrypt.ToSafeString() + " mech " + mech.ToSafeString(), command);
if (encrypt)
{
session.EncryptInit(mech, key);
byte[] enc = session.Encrypt(input);
session.EncryptFinal();
session.Logout();
session.Close();
tupla.Item2.Finalize(IntPtr.Zero);
return enc;
}
else
{
session.DecryptInit(mech, key);
byte[] decriptata = session.Decrypt(input);
session.DecryptFinal();
session.Logout();
session.Close();
tupla.Item2.Finalize(IntPtr.Zero);
return decriptata;
}
}
catch (Exception e)
{
session.Logout();
session.Close();
tupla.Item2.Finalize(IntPtr.Zero);
Utility.Logger("Crypto " + e.ToSafeString(), command);
return null;
}
}
Where openSessionTupla is
public static Tuple<Session, Cryptoki> openSessionTupla()
{
Cryptoki.Licensee = Settings.LICENSEE;
Cryptoki.ProductKey = Settings.PRODUCTKEY;
Cryptoki cryptoki = new Cryptoki(Settings.PATH);
//Console.WriteLine(Settings.PATH);
//Console.WriteLine(Settings.SessionKey);
cryptoki.Initialize();
SlotList slots = cryptoki.Slots;
if (slots.Count == 0)
{
//Console.WriteLine("No slot available");
return null;
}
// Gets the first slot available
Slot slot = slots[0];
if (!slot.IsTokenPresent)
{
//Console.WriteLine("No token inserted in the slot: " + slots[0].Info.Description);
return null;
}
Token token = slot.Token;
var flags = token.Info.Flags;
//token.Info.Flags = 1609;
Session session = token.OpenSession(Session.CKF_SERIAL_SESSION | Session.CKF_RW_SESSION,
null,
null);
int nRes = session.Login(Session.CKU_USER, Settings.SessionKey);
return new Tuple<Session, Cryptoki>(session, cryptoki);
}
Maybe the call to session.EncryptInit(mech, key) returns an error.
this is why the subsequent call to Encrypt returns CKR_OPERATION_NOT_INITIALIZED
You should write:
long nRes = session.EncryptInit(mech, key);
if(nRer != 0) {
// manage the error
}
else {
byte[] enc = session.Encrypt(input);
session.EncryptFinal();
}
I am kinda new to cryptography, and a requirement needs me to
"Create or retrieve user’s RSA-OAEP key. There should be one
public/private key pair for each user for a device"
and send it to the server in this form:
{"modulus":"qMBRpdYrAy5aMmo31NErUizh5sbweguSmh4wlK6uJEIDl+kwTlROnE34KOFExeTbJSX0WygPi+vWl0yNq7buIMUKpytossAAWut5khO3CQJxTk7G2gnEPNUUXHiExGgNrLzcSLv8YIlfVALhoRWyC67KOL+a+3taNq3h+BHeWhM=","exponent":"AQAB"}
I tried the OpenSSL commands to generate RSA public/private key pair, and it comes out like this:
Public key (have changed the value by a bit for security):
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4NMwqhswK6Py+N1OlPBn3JelqEdZ8YwSn4j1Kvp5HK+pS/5gcABkx/89buDhhtKvZ8mfSNkhKHU2WuBPIikGAvEKbbbQ8DHKubHa07X1xTgY+qMyxTLaHnaEC6oOi6BixPfo6QAm+SnqxBWuvDPBzGqSS+/p5r7aydLBAlkoZ+DzpBbAHIIK72c+xqCL8oOFz4QqsVMakdKQ+fVdM1e8U2ak4ygHOleqJgcl8+xH7TFJsvUOfsgsMlz2FmNXWhCYUdOKglP8ZUVMuiAW9KEjAFta4xEf3bBGRDYss7mLQF5/RHbpzYeNwQ1RVp8bhTumpQytqJZshUj8DA3oqMFUr xyz#xyz.xyz
Private key (have altered the value by a bit for security):
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,67A126EE3266B641AF4AC698AA18FE01
3w4GI7HfymD0A8+LokUbsIiI50CJfszBjO5PR4tW532ccKVMQRKywBMANUWx5B66
Mkr/uY9lH8mJOhWrwwiXCUFKMtDGcC06NHbIWIAu/TP85TidwhtGABqSYkjh+8Hm
SlwTMe2xjPq+X8Xc8+vW6Ng8mvXST0Ezz4DiTKA9yeH0eVxIQ4WIpvO7X9793xSD
FoXQ5sCY7Mr6GBNxln4f9cy5BwEsEGa86dtzXVkK8Gu8xRy28GE4W7D6/eNkgl6B
ovEuuC7IDibP/qrGAq/Nxdrl6QrnFTd2FcQfbR4jeArC+IaeXAxXgqhhTJH9ySk8
ZnEaMIruEGvRbChwzlvqS/sCMcS8eoD22Di94Gmkv4thSIWuk1MTRMTKFTMAgVOb
8shCKgCR5FJXjPHV8sUhIwk4TrQWX70fWM3QmBq3ue2AnGonWXhzXQU7jB36zATm
dhpsHZ2/80BuB/hMnFJpsjcYU16pm9BunSMs7tyMW3X3F91x6liC3j2ItUjEkPME
P6eZE2KDM+QxlDLfebL+bGMN6rYvEmfvKo44nwNIMnJM9J3ZYNM9KGt87B4loVwn
TeWIGrCQ9SRCpiAVbZj+M9DDDuqxSoA0wxSDrcYjWt8trzS20AWj7lsxBQgUvpBX
nuFAQgMgT4DK9X2z9ESplXi/l2uZ0iDBTN4SEHI3oR3ar2rWSjoQrTTfOg7cYlF1
ewLR6toCEEvturC4vLyWyrDIu3P/jiSz6eiSTeI9W02rQ/qILUrouKx1LwviIKR2
OGQnkzm3iiNq0jykzObwCsDLuY6rA4nv/ZBsjLDWB34gveKSzOrtx4dzqmtcv0Kq
ndua6xdaPmpV3n4slRD1PxSwNgKb4qwlYuQMPKLhCXUq4yG59IOoH7yfxS5UZ7wa
yndGMLMPmylcHDLX02U90X3feUcC9IiE7z6pOILy4uC28Z2X5KYjoK07pwA+5lNt
9RvryaK4IXysJZ5zqsBUaeYlqqBATcEPYn3YXbT5cSaxkv4lI36g6iG7/QmA3PGt
1l57kBW2xnUSrqm5XtZZMrsSu2iZ9Hiuh73SRkODjg7ToEMtwLECkN1TRL9PVEQj
QHAxauWleC+2yB0+1XH7/CywkYk2HxeNQJJDsWU+XJM/RFGFNV481LwfU0Hw58sZ
ai4R2LmDDoy4wwtcQGkY13ZHT8h/jxP4/Sr36GJdVkhhUCDnpFfdNHebgflj0PQg
eTHVY/6GqfnKvneOGtDRR4EkBFopUV5OLzuRX3z/rlHRV1iPCaqhooL9XO320JYq
xY5YMWq7tvgzE5jtqo65AwO8WWs12NTzG1KRhcXCyYE4Da1T6k7l8++MOeVGZy1v
qDxEddTfiAzIvCme2lEiYOb2/UUNAhEM+Ave/lfWmirW5dSAOppZenHUnuZh9eVd
iFVswrAxcd4BqA5GGczzu9EIqdzpspTrnG3hxOf+tXEXf3TTAH/sTVfQGQHO1iRd
UTh9FGgHk3WMswBnYyfpbSOR8Mghab966RRYP2xBCVJEvCymYuUE11x6vsvQFpGS
X2SEhOpzgINuKZRTuVmhK1oXRt3BZO8yQ13t+wtQCP6a8azS+Sc436aDqBlWQfJ2
-----END RSA PRIVATE KEY-----
How can I extract the modulus and exponent in the form that server expects from this data?
You can simply get the format from RFC 4253 but you need to find out what the mpint (multi-precission integer) format is from RFC 4251.
Here's the thing in Java (just Java), simply because the JSch library is so horrible.
package nl.owlstead.crypto;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.Base64.Encoder;
public class SSHPublicKeyDecoder {
private static byte[] SSH_RSA_HEADER = "ssh-rsa".getBytes(StandardCharsets.US_ASCII);
private static RSAPublicKey decodeRSAPublicKey(byte[] encodedRSAPublicKey)
throws NoSuchAlgorithmException, InvalidKeySpecException {
ByteBuffer buf = ByteBuffer.wrap(encodedRSAPublicKey);
byte[] header = getSSHEncodedValueFromBuffer(buf);
if (!Arrays.equals(header, SSH_RSA_HEADER)) {
throw new IllegalArgumentException("Not an RSA public key");
}
byte[] eDataSigned = getSSHEncodedValueFromBuffer(buf);
BigInteger e = new BigInteger(eDataSigned);
byte[] nDataSigned = getSSHEncodedValueFromBuffer(buf);
BigInteger n = new BigInteger(nDataSigned);
KeyFactory rsaKeyFactory;
try {
rsaKeyFactory = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException ex) {
throw new IllegalStateException(
"KeyFactory should exist for RSA", ex);
}
RSAPublicKeySpec spec = new RSAPublicKeySpec(n, e);
return (RSAPublicKey) rsaKeyFactory.generatePublic(spec);
}
private static byte[] getSSHEncodedValueFromBuffer(ByteBuffer buf) {
int size = buf.getInt();
if (size < 0) {
throw new IllegalArgumentException("Bad SSH encoded value in format");
}
byte[] data = new byte[size];
buf.get(data);
return data;
}
private static byte[] toUnsigned(BigInteger value) {
if (value.compareTo(BigInteger.ZERO) <= 0) {
throw new IllegalArgumentException("Negative numbers cannot be encoded as unsigned integers");
}
if (value.equals(BigInteger.ZERO)) {
return value.toByteArray();
}
final byte[] signedBigEndian = value.toByteArray();
if (signedBigEndian[0] == 0x00) {
return Arrays.copyOfRange(signedBigEndian, 1, signedBigEndian.length);
}
return signedBigEndian;
}
private SSHPublicKeyDecoder() {
}
public static void main(String[] args) throws Exception {
String[] parts = args[0].split("\\s+");
String part2 = parts[1];
byte[] encodedRSAPublicKey = Base64.getDecoder().decode(part2);
RSAPublicKey pubKey = decodeRSAPublicKey(encodedRSAPublicKey);
String format = encodeServerPublicKey(pubKey);
System.out.println(format);
}
private static String encodeServerPublicKey(RSAPublicKey pubKey) {
byte[] nData = toUnsigned(pubKey.getModulus());
byte[] eData = toUnsigned(pubKey.getPublicExponent());
Encoder base64Encoder = Base64.getEncoder();
String format = String.format(
"{\"modulus\":\"%s\",\"exponent\":\"%s\"}%n",
base64Encoder.encodeToString(nData),
base64Encoder.encodeToString(eData));
return format;
}
}
My program is caught in a cycle that never ends, and I can't see how it get into this trap, or how to avoid it.
It's parsing Wikipedia data and I think it's just following a connected component around and around.
Maybe I can store the pages I've visited already in a set and if a page is in that set I won't go back to it?
This is my project, its quite small, only three short classes.
This is a link to the data it generates, I stopped it short, otherwise it would have gone on and on.
This is the laughably small toy input that generated that mess.
It's the same project I was working on when I asked this question.
What follows is the entirety of the code.
The main class:
public static void main(String[] args) throws Exception
{
String name_list_file = "/home/matthias/Workbench/SUTD/nytimes_corpus/NYTimesCorpus/2005/01/02/test/people_test.txt";
String single_name;
try (
// read in the original file, list of names, w/e
InputStream stream_for_name_list_file = new FileInputStream( name_list_file );
InputStreamReader stream_reader = new InputStreamReader( stream_for_name_list_file , Charset.forName("UTF-8"));
BufferedReader line_reader = new BufferedReader( stream_reader );
)
{
while (( single_name = line_reader.readLine() ) != null)
{
//replace this by a URL encoder
//String associated_alias = single_name.replace(' ', '+');
String associated_alias = URLEncoder.encode( single_name , "UTF-8");
String platonic_key = single_name;
System.out.println("now processing: " + platonic_key);
Wikidata_Q_Reader.getQ( platonic_key, associated_alias );
}
}
//print the struc
Wikidata_Q_Reader.print_data();
}
The Wikipedia reader / value grabber:
static Map<String, HashSet<String> > q_valMap = new HashMap<String, HashSet<String> >();
//public static String[] getQ(String variable_entity) throws Exception
public static void getQ( String platonic_key, String associated_alias ) throws Exception
{
//get the corresponding wikidata page
//check the validity of the URL
String URL_czech = "https://www.wikidata.org/wiki/Special:ItemByTitle?site=en&page=" + associated_alias + "&submit=Search";
URL wikidata_page = new URL(URL_czech);
HttpURLConnection wiki_connection = (HttpURLConnection)wikidata_page.openConnection();
InputStream wikiInputStream = null;
try
{
// try to connect and use the input stream
wiki_connection.connect();
wikiInputStream = wiki_connection.getInputStream();
}
catch(IOException e)
{
// failed, try using the error stream
wikiInputStream = wiki_connection.getErrorStream();
}
BufferedReader wiki_data_pagecontent = new BufferedReader(
new InputStreamReader(
wikiInputStream ));
String line_by_line;
while ((line_by_line = wiki_data_pagecontent.readLine()) != null)
{
// if we can determine it's a disambig page we need to send it off to get all
// the possible senses in which it can be used.
Pattern disambig_pattern = Pattern.compile("<div class=\"wikibase-entitytermsview-heading-description \">Wikipedia disambiguation page</div>");
Matcher disambig_indicator = disambig_pattern.matcher(line_by_line);
if (disambig_indicator.matches())
{
//off to get the different usages
Wikipedia_Disambig_Fetcher.all_possibilities( platonic_key, associated_alias );
}
else
{
//get the Q value off the page by matching
Pattern q_page_pattern = Pattern.compile("<!-- wikibase-toolbar --><span class=\"wikibase-toolbar-container\"><span class=\"wikibase-toolbar-item " +
"wikibase-toolbar \">\\[<span class=\"wikibase-toolbar-item wikibase-toolbar-button wikibase-toolbar-button-edit\"><a " +
"href=\"/wiki/Special:SetSiteLink/(.*?)\">edit</a></span>\\]</span></span>");
Matcher match_Q_component = q_page_pattern.matcher(line_by_line);
if ( match_Q_component.matches() )
{
String Q = match_Q_component.group(1);
// 'Q' should be appended to an array, since each entity can hold multiple
// Q values on that basis of disambig
put_to_hash( platonic_key, Q );
}
}
}
wiki_data_pagecontent.close();
// \\ // ! PRINT IT ! // \\ // \\ // \\ // \\ // \\ // \\
for (Map.Entry<String, HashSet<String> > entry : q_valMap.entrySet())
{
System.out.println(entry.getKey()+" : " + Arrays.deepToString(q_valMap.entrySet().toArray()) );
}
}
// add Q values to their arrayList in the hash map at the index of the appropriate entity
public static HashSet<String> put_to_hash(String key, String value )
{
HashSet<String> valSet;
if (q_valMap.containsKey(key)) {
valSet = q_valMap.get(key);
} else {
valSet = new HashSet<String>();
q_valMap.put(key, valSet);
}
valSet.add(value);
return valSet;
}
// add Q values to their arrayList in the hash map at the index of the appropriate entity
public static void print_data()
{
System.out.println("THIS IS THE FINAL DATA SET!!!");
// \\ // ! PRINT IT ! // \\ // \\ // \\ // \\ // \\ // \\
for (Map.Entry<String, HashSet<String> > entry : q_valMap.entrySet())
{
System.out.println(entry.getKey()+" : " + Arrays.deepToString(q_valMap.entrySet().toArray()) );
}
}
Dealing with disambiguation pages:
public static void all_possibilities( String platonic_key, String associated_alias ) throws Exception
{
System.out.println("this is a disambig page");
//if it's a disambig page we know we can go right to the Wikipedia
//get it's normal wiki disambig page
String URL_czech = "https://en.wikipedia.org/wiki/" + associated_alias;
URL wikidata_page = new URL(URL_czech);
HttpURLConnection wiki_connection = (HttpURLConnection)wikidata_page.openConnection();
InputStream wikiInputStream = null;
try
{
// try to connect and use the input stream
wiki_connection.connect();
wikiInputStream = wiki_connection.getInputStream();
}
catch(IOException e)
{
// failed, try using the error stream
wikiInputStream = wiki_connection.getErrorStream();
}
// parse the input stream using Jsoup
Document docx = Jsoup.parse(wikiInputStream, null, wikidata_page.getProtocol()+"://"+wikidata_page.getHost()+"/");
//this can handle the less structured ones.
Elements linx = docx.select( "p:contains(" + associated_alias + ") ~ ul a:eq(0)" );
for (Element linq : linx)
{
System.out.println(linq.text());
String linq_nospace = URLEncoder.encode( linq.text() , "UTF-8");
Wikidata_Q_Reader.getQ( platonic_key, linq_nospace );
}
}
while encrypting and descripting the string with rsa provider I am getting this error.
RSA Data decryption error.The data to be decrypted exceeds the maximum for this modulus of 64 bytes.
Can any one have idea how to slove this error?
internal sealed class RSAProvider
{
#region key store class
[Serializable]
private struct rsaKey
{
public rsaKey(RSAParameters rsaKeyInfo)
{
D = rsaKeyInfo.D;
DP = rsaKeyInfo.DP;
DQ = rsaKeyInfo.DQ;
Exponent = rsaKeyInfo.Exponent;
InverseQ = rsaKeyInfo.InverseQ;
Modulus = rsaKeyInfo.Modulus;
P = rsaKeyInfo.P;
Q = rsaKeyInfo.Q;
}
public RSAParameters CreateRSAKey()
{
RSAParameters rsaKeyInfo = new RSAParameters();
rsaKeyInfo.D = D;
rsaKeyInfo.DP = DP;
rsaKeyInfo.DQ = DQ;
rsaKeyInfo.Exponent = Exponent;
rsaKeyInfo.InverseQ = InverseQ;
rsaKeyInfo.Modulus = Modulus;
rsaKeyInfo.P = P;
rsaKeyInfo.Q = Q;
return rsaKeyInfo;
}
public byte[] D;
public byte[] DP;
public byte[] DQ;
public byte[] Exponent;
public byte[] InverseQ;
public byte[] Modulus;
public byte[] P;
public byte[] Q;
}
#endregion
private static RSAParameters rsaKeyParameters;
static RSAProvider()
{
string rsaKeyString = System.Configuration.ConfigurationSettings.AppSettings["RSAKey"];
if(rsaKeyString != null)
{
rsaKeyParameters = GetKeyByString(rsaKeyString);
}
}
private RSAProvider()
{
}
private static RSAParameters RSAKeyInfo
{
get
{
return rsaKeyParameters;
}
}
private static bool DoOAEPPadding
{
get
{
return false;
}
}
public static string GenerateKey(int keySize)
{
//Create a new instance of RSACryptoServiceProvider to generate
//public and private key data.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(keySize);
RSAParameters rsaKeyInfo = RSA.ExportParameters(true);
return GetKeyString(rsaKeyInfo);
}
#region Encrypt
public static byte[] Encrypt(byte[] dataToEncrypt, string rsaKeyString)
{
RSAParameters rsaKeyInfo = GetKeyByString(rsaKeyString);
return Encrypt(dataToEncrypt, rsaKeyInfo);
}
public static byte[] Encrypt(byte[] dataToEncrypt, RSAParameters rsaKeyInfo)
{
try
{
//Create a new instance of RSACryptoServiceProvider.
// Common.Identity.ImpersonateValidUser("prana", "eetplpvt", "Avdhoota1985");
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Import the RSA Key information. This only needs
//toinclude the public key information.
RSA.ImportParameters(rsaKeyInfo);
//Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
//return RSA.Encrypt(dataToEncrypt, DoOAEPPadding);
byte[] data = RSA.Encrypt(dataToEncrypt, DoOAEPPadding);
RSA.Clear();
//Common.Identity.UndoImpersonation();
return data;
}
//Catch and display a CryptographicException
//to the console.
catch(CryptographicException e)
{
// Updated By Divya Bhalodia on 27th June 2008 for Localization task
//throw new Exception("Data encryption error.", e);
Common.EnumLocalization.EnumLocalization loc = new Common.EnumLocalization.EnumLocalization(ASP.BL.ApplicationUsers.ApplicationUserController.CurrentUserCulture.Code, ASP.BL.Applications.ApplicationController.CurrentApplicationInfo.ItemId);
throw new Exception(loc.LocalizeString("RSA Data encryption error.") + e.Message, e);
// end Updated - Divya
}
}
public static byte[] Encrypt(byte[] dataToEncrypt)
{
return Encrypt(dataToEncrypt, RSAKeyInfo);
}
#endregion
#region Decrypt
public static byte[] Decrypt(byte[] dataToDecrypt, string rsaKeyString, bool doOAEPPadding)
{
RSAParameters rsaKeyInfo = GetKeyByString(rsaKeyString);
return Decrypt(dataToDecrypt, rsaKeyInfo, doOAEPPadding);
}
public static byte[] Decrypt(byte[] dataToDecrypt, RSAParameters rsaKeyInfo, bool doOAEPPadding)
{
try
{
//Create a new instance of RSACryptoServiceProvider.
Common.Identity.ImpersonateValidUser();
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(rsaKeyInfo);
//Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
//return RSA.Decrypt(dataToDecrypt, doOAEPPadding);
byte[] data = RSA.Decrypt(dataToDecrypt, doOAEPPadding);
RSA.Clear();
Common.Identity.UndoImpersonation();
return data;
}
//Catch and display a CryptographicException
//to the console.
catch(CryptographicException e)
{
// Updated By Divya Bhalodia on 27th June 2008 for Localization task
//throw new Exception("Data decryption error.", e);
Common.EnumLocalization.EnumLocalization loc = new Common.EnumLocalization.EnumLocalization(ASP.BL.ApplicationUsers.ApplicationUserController.CurrentUserCulture.Code, ASP.BL.Applications.ApplicationController.CurrentApplicationInfo.ItemId);
throw new Exception(loc.LocalizeString("RSA Data decryption error.") + e.Message, e);
// end Updated - Divya
}
}
public static byte[] Decrypt(byte[] dataToDecrypt)
{
return Decrypt(dataToDecrypt, RSAKeyInfo, DoOAEPPadding);
}
#endregion
#region Additional functions
private static string GetKeyString(RSAParameters rsaKeyInfo)
{
byte[] tmp;
rsaKey k = new rsaKey(rsaKeyInfo);
BinaryFormatter formater = new BinaryFormatter();
using(MemoryStream stream = new MemoryStream())
{
formater.Serialize(stream, k);
tmp = stream.ToArray();
}
Code(tmp);
return Convert.ToBase64String(tmp);
}
private static RSAParameters GetKeyByString(string rsaKeyString)
{
rsaKey k;
byte[] tmp = Convert.FromBase64String(rsaKeyString);
Code(tmp);
BinaryFormatter formater = new BinaryFormatter();
using(MemoryStream stream = new MemoryStream(tmp))
{
k = (rsaKey)formater.Deserialize(stream);
}
return k.CreateRSAKey();
}
private static void Code(byte[] tmp)
{
byte mask1 = 0x55;
byte mask3 = 0xB9;
byte mask4 = 0xCF;
for(int i = 0; i
I've encoutered similar problems but you can do two things to help yourself overcome them.
You need to ensure that hte data you are encrypting is shorter than the key that you are using. so if your key is 1024 bits then make sure that you are only bassing in say 1000 bits. To do this you need to get chunk your byte array into smaller chunks, encrypt each chunk and then store the encrypeted value in an array or a string. So instead of encrypting 1 string you encrypt say 5 strings.
When storing this information as a string make sure that all numbers are the same length, so if the formatter returns 15 you store the string with 015 so that you just divide by 3 later to get the byte to then put into the array.
To decrypt your data you need to simply read the length of the string and determine how many chunks to decrypt. Decrupt these one by one and then you can recreate the object with the decrupted byte array.
if you would like actual code please contact me personally and I'll be able to help you better with some script that can do this for you.