I have a problem.
I must get a md5 hash of string in Java ME.
I have that code
public static String md5(String input) throws UnsupportedEncodingException{
String res = "";
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(input.getBytes("UTF-8"));
byte[] md5 = algorithm.digest();
return md5.toString();
}
catch (NoSuchAlgorithmException ex) {}
return res;
}
But MessageDigest.update() and MessageDigest.digest() accept only 3 arguments.
Any ideas?
The two other arguments are offset and len, which you can set to 0 and the length of the byte buffer respectively.
Related
I want to convert Properties object to byte[], however i can do with the following piece of code but
private byte[] getBytes(Properties properties){
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter=new PrintWriter(stringWriter);
properties.list(printWriter);
String fileContent = stringWriter.getBuffer().toString();
byte[] bytes = fileContent.getBytes();
try{
stringWriter.close();
printWriter.close();
}catch (IOException e){
log.error("unable to close resource stringWriter" + e.getStackTrace());
}
return bytes;
}
but properties.list(printWriter), will print the string "--listing properties--" string to the console. Need help in finding the best way to do it.
I used a ByteArrayOutputStream to convert a Properties object. Your function could be modified to be the following -
private byte[] getBytes(Properties properties){
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
props.store(byteArrayOutputStream, "");
} catch (IOException e) {
log.error("An error occurred while storing properties to a byte array: " + e.getStackTrace());
}
return byteArrayOutputStream.toByteArray();
}
Properties file contains plain text, so to store a byte array you need to encode bytes to plain text. The best way is to use Base64 encodec.
String Base64.econdeToString(byte[])
And to retrieve bytes:
byte[] Base64.decode(String)
I am trying to generate ECDSA key pair using SpongyCastle in Android.
This is the code:
static {
Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
}
public static KeyPair generate() {
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
KeyPairGenerator generator = KeyPairGenerator.getInstance("ECDSA", "SC");
generator.initialize(ecSpec, new SecureRandom());
KeyPair keyPair = g.generateKeyPair();
Log.i(TAG, "EC Pub Key generated: " + utils.bytesToHex(keyPair.getPublic().getEncoded()));
Log.i(TAG, "EC Private Key generated: " + utils.bytesToHex(keyPair.getPrivate().getEncoded()));
return generator.generateKeyPair();
}
Something is wrong since I always get something like that example of
Public Key:
3059301306072A8648CE3D020106082A8648CE3D03010703420004483ABA9F322240010ECF00E818C041A60FE71A2BD64C64CD5A60519985F110AEDE6308027D2730303F5E2478F083C7F5BB683DCAC22BFEB62F3A48BD01009F40
and Private Key:
308193020100301306072A8648CE3D020106082A8648CE3D030107047930770201010420219AB4B3701630973A4B2917D53F69A4BE6DAD61F48016BFEF147B2999575CB2A00A06082A8648CE3D030107A14403420004483ABA9F322240010ECF00E818C041A60FE71A2BD64C64CD5A60519985F110AEDE6308027D2730303F5E2478F083C7F5BB683DCAC22BFEB62F3A48BD01009F40
The site ECDSA sample give me "Invalid ECDSA signature message", and them seems really very different from that smaller Private Key and always starting with "04" Public Key generated in the same site.
Also, my backend verification gives me the error "Invalid point encoding 0x30"
The backend Java method check is:
public ECPublicKey getPublicKeyFromHex(String publicKeyHex)
throws NoSuchAlgorithmException, DecoderException, ApplicationGenericException {
byte[] rawPublicKey = Hex.decodeHex(publicKeyHex.toCharArray());
ECPublicKey ecPublicKey = null;
KeyFactory kf = null;
ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
ECCurve curve = ecNamedCurveParameterSpec.getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecNamedCurveParameterSpec.getSeed());
java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, rawPublicKey);
java.security.spec.ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve,
ecNamedCurveParameterSpec);
java.security.spec.ECPublicKeySpec publicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint,
ecParameterSpec);
kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
try {
ecPublicKey = (ECPublicKey) kf.generatePublic(publicKeySpec);
} catch (Exception e) {
throw new ApplicationGenericException(e.getMessage(), e.getCause());
}
return ecPublicKey;
}
Java's default encoding for a PublicKey is "X.509" which is not just the EC point; it is an ASN.1 structure identifying the algorithm (EC) and parameters (here prime256v1) PLUS a BIT STRING wrapping the point; see rfc5280 section 4.2.1.7 and rfc3279 section 2.3.5.
Similarly the default encoding for PrivateKey is "PKCS#8" (unencrypted) which is a structure containing an AlgorithmIdentifier plus an OCTET STRING wrapping the data which in this case contains both the private key value and a copy of the public key, see rfc5208 section 5 and C.4 of document SEC 1 at http://www.secg.org with tag [0] omitted but tag [1] present.
To read (either or both of) them back in to Java, get a KeyFactory.getInstance("EC") and use generate{Public,Private} on an X509EncodedKeySpec or PKCS8EncodedKeySpec respectively.
ECDSA and ECDH (and ECMQV etc) use the same key structures, unlike classic integer DSA and DH which use the same mathematical structure ($Z_p^*$) but slightly different representations.
PS: the javadoc for java.security.Key tells you most of this.
More practical example. Convert generated public key to decoded bytes array or hex string:
public String getPublicKeyAsHex(PublicKey publicKey){
ECPublicKey ecPublicKey = (ECPublicKey)publicKey;
ECPoint ecPoint = ecPublicKey.getW();
byte[] publicKeyBytes = new byte[PUBLIC_KEY_LENGTH];
writeToStream(publicKeyBytes, 0, ecPoint.getAffineX(), PRIVATE_KEY_LENGTH);
writeToStream(publicKeyBytes, PRIVATE_KEY_LENGTH, ecPoint.getAffineY(), PRIVATE_KEY_LENGTH);
String hex = Hex.toHexString(publicKeyBytes);
logger.debug("Public key bytes: " + Arrays.toString(publicKeyBytes));
logger.debug("Public key hex: " + hex);
return hex;
}
private void writeToStream(byte[] stream, int start, BigInteger value, int size) {
byte[] data = value.toByteArray();
int length = Math.min(size, data.length);
int writeStart = start + size - length;
int readStart = data.length - length;
System.arraycopy(data, readStart, stream, writeStart, length);
}
Convert decoded bytes array back to PublicKey:
KeyFactory factory = KeyFactory.getInstance(ALGORITHM, ALGORITHM_PROVIDER);
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(CURVE);
ECNamedCurveSpec params = new ECNamedCurveSpec(CURVE, spec.getCurve(), spec.getG(), spec.getN());
BigInteger xCoordinate = new BigInteger(1, Arrays.copyOfRange(decodedPublicKey, 0, PRIVATE_KEY_LENGTH));
BigInteger yCoordinate = new BigInteger(1, Arrays.copyOfRange(decodedPublicKey, PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH));
java.security.spec.ECPoint w = new java.security.spec.ECPoint(xCoordinate, yCoordinate);
PublicKey encodedPublicKey = factory.generatePublic(new java.security.spec.ECPublicKeySpec(w, params));
is it possible or is there any overload to get a less than 32 characters of GUID ?
currently i am using this statement but its giving me error
string guid = new Guid("{dddd-dddd-dddd-dddd}").ToString();
i want a key of 20 characters
You can use a ShortGuid. Here is an example of an implementation.
It's nice to use ShortGuids in URLs or other places visible to an end user.
The following code:
Guid guid = Guid.NewGuid();
ShortGuid sguid1 = guid; // implicitly cast the guid as a shortguid
Console.WriteLine( sguid1 );
Console.WriteLine( sguid1.Guid );
Will give you this output:
FEx1sZbSD0ugmgMAF_RGHw
b1754c14-d296-4b0f-a09a-030017f4461f
This is the code for an Encode and Decode method:
public static string Encode(Guid guid)
{
string encoded = Convert.ToBase64String(guid.ToByteArray());
encoded = encoded
.Replace("/", "_")
.Replace("+", "-");
return encoded.Substring(0, 22);
}
public static Guid Decode(string value)
{
value = value
.Replace("_", "/")
.Replace("-", "+");
byte[] buffer = Convert.FromBase64String(value + "==");
return new Guid(buffer);
}
Use Jeff Attwood's ASCII85...
http://www.codinghorror.com/blog/2005/10/equipping-our-ascii-armor.html
and
http://www.codinghorror.com/blog/2005/10/c-implementation-of-ascii85.html
I have a website in asp.net 2.0, As I need to use CCNOW payment integration to make a payment but for this I'll have to send request to CCNOW in MD5 format but I can't able to generate my values to CCNOW MD5 format. So, could you please any one have a script/function that will convert given string into MD5?
MD5 isn't a "format," is a hashing algorithm. Use the MD5 class. Assuming you're using C#, it would look something like this:
static string getMd5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
public static string GetMD5(string value) {
MD5 md5 = MD5.Create();
byte[] md5Bytes = System.Text.Encoding.Default.GetBytes(value);
byte[] cryString = md5.ComputeHash(md5Bytes);
string md5Str = string.Empty;
for (int i = 0; i < cryString.Length; i++) {
md5Str += cryString[i].ToString("X");
}
return md5Str;
}
Call it with:
GetMD5(stringToConvert);
I am doing encryption and decryption using AES Algorithm with bouncy castle
My encryption and decryption works ok but it gives me error when my plain text size is bigger
even sometimes it is giving non decrypted data
public static boolean setEncryptionKey(String keyText)
{
byte[] keyBytes = keyText.getBytes();
key = new KeyParameter(keyBytes);
engine = new AESFastEngine();
cipher = new PaddedBufferedBlockCipher(engine);
return true;
}
Encryption:
public static String encryptString(String plainText)
{
byte[] plainArray = plainText.getBytes();
cipher.init(true, key);
byte[] cipherBytes = new byte[cipher.getOutputSize(plainArray.length)];
int cipherLength = cipher.processBytes(plainArray, 0, plainArray.length, cipherBytes, 0);
cipher.doFinal(cipherBytes, cipherLength);
String cipherString = new String(cipherBytes);
return cipherString;
}
Decryption:
public static String decryptString(String encryptedText)
{
byte[] cipherBytes = encryptedText.getBytes();
cipher.init(false, key);
byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
int decryptedLength = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decryptedBytes, 0);
cipher.doFinal(decryptedBytes, decryptedLength);
String decryptedString = new String(decryptedBytes);
int index = decryptedString.indexOf("\u0000");
if (index >= 0)
{
decryptedString = decryptedString.substring(0, index);
}
return decryptedString;
}
This decryption is giving me following error
org.bouncycastle.crypto.InvalidCipherTextException: pad block corrupted
at org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(+30)
at org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(+190)
at com.NewCrypto.decryptString(NewCrypto.java:103)
at com.New_Midlet.startApp(New_Midlet.java:23)
at javax.microedition.midlet.MIDletProxy.startApp(MIDletProxy.java:44)
at com.sun.midp.midlet.Scheduler.schedule(Scheduler.java:375)
at com.sun.midp.main.Main.runLocalClass(Main.java:477)
at com.sun.midp.main.Main.main(+80)
what could be the problem ?
The line
String cipherString = new String(cipherBytes);
is a bug. cipherBytes is a byte array with arbitrary values and cannot be converted to a string using any of the Java string decoders. You should just send/save the cipher as a byte array. If you must make it a string then you'll have to use an encoder. Base64 encoders are often used, as are Base16 (hex). You can use the Apache Commons Codec or my favorite, the Harder Base64 codec.