I am trying to calculate CMAC
byte[] key={0x09,0x11,0x12,0x34,0x56,0x78,0x00,0x01,0x01,0x13,0x14,0x36,0x58,0x7A,0x02,0x03};
AES mAES=new AES();
mAES.AesInit(key);
byte[] response = mAES.calcCMAC(challenge);
Swift i am using the lib CryptoSwift
let key = [0x09,0x11,0x12,0x34,0x56,0x78,0x00,0x01,0x01,0x13,0x14,0x36,0x58,0x7A,0x02,0x03] as [UInt8]
let message:NSData = NSData.fromHexString("DA55C255")
let mac = Authenticator.Poly1305(key: key).authenticate(message.arrayOfBytes())
But it's not working as expected.
the expected result is
Challenge isDA55C255
Response isED7CA01A
we don't find any solution, we have created our own classe
https://gist.github.com/bolom/b426a0163943b576175b
Related
am trying to make a signature for a HTTP request ,
using flutter/dart for the app and the server in NodeJs
but i have a problem there is little different between the two signature
any idea what cause that
EEFSxb_coHvGM-69RhmfAlXJ9J0= //signature in dart
EEFSxb/coHvGM+69RhmfAlXJ9J0= //signature in nodejs
signature.dart
var key = "key";
var data = "data";
List<int> signingKey = utf8.encode("key");
List<int> signatureBaseString = utf8.encode("data");
var hmacSha1 = Hmac(sha1, signingKey);
var digest = hmacSha1.convert(signatureBaseString);
var hashInBase = base64Url.encode(digest.bytes);
print(hashInBase) ; // result : EEFSxb_coHvGM-69RhmfAlXJ9J0=
signature.js
var data = "data" ;
var key = "key" ;
var output = encodeURIComponent(data);
var keyO = encodeURIComponent(key);
var hashed = CryptoJS.HmacSHA1(output , keyO);
var hashInBase = CryptoJS.enc.Base64.stringify(hashed);
console.log(hashInBase); // result : EEFSxb/coHvGM+69RhmfAlXJ9J0=
There are two styles of Base64 encoding which use slightly different character sets for the 64 characters. (You get 52 from the upper and lower case letters and ten more from the numbers, so a couple more ascii chars are needed to make up the 64 - plus the special trailing equals.)
The / and + characters have special meanings in URLs, so can be replaced in the alternative "URL safe" encoding with _ and -. Note also that the trailing equals can be dropped.
It seems you may be trying to compare base64 encoded strings to test for equality. It's safer to decode from base 64 and compare the byte arrays.
Anyway, to solve you problem, don't use the Dart URL safe version, use the regular version: base64.encode()
I am trying to obtain the results of a hmac sha256 as a String ,something similar to this "asdafsdfafs13rfafAafaasdfadfasdfa", but the code snippet below generates this 👇🏻👇🏻 byteArray.
var combinedString = "key1=val1&key2=val2"
//Using import BlueCryptor
let key = CryptoUtils.byteArray(fromHex: apikey!)
let data : [UInt8] = CryptoUtils.byteArray(fromHex: combinedString)
let hmac = HMAC(using: HMAC.Algorithm.sha256, key: key).update(byteArray: data)?.final()
print(hmac)
How do i convert it from a byteArray to a string ?
I'm passing password into sha256. I successfully create sha256 and can also print it. The problem begins when I'm trying to convert digest.bytes into a string and append it.
import 'package:crypto/crypto.dart';
var url = "http://example_api.php?";
url += '&hash=';
// hash the password
var bytes = utf8.encode(password);
var digest = sha256.convert(bytes);
print("Digest as hex string: $digest");
url += String.fromCharCodes(digest.bytes);
This is printed: Digest as hex string: 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
This is appended to url: ¬gBóá\vá¥âUðg6#ȳ´Eùx×ÈFô
What am I doing wrong? I also tried utf8.decode method but using it gives me an error.
When you print digest, the print method will call digest.toString(), which is implemented to return a string of the digest bytes using a hexadecimal representation. If you want the same thing you have several options:
Call digest.toString() explicitly (or implicitly)
final digestHex = digest.toString(); // explicitly
final digestHex = '$digest'; // implicitly
Map the byte array to its hexadecimal equivalent
final digestHex = digest.bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
Use the convert package (this is what the crypto package does)
import 'package:convert/convert.dart';
...
final digestHex = hex.encode(digest.bytes);
The reason you are getting an error using utf8.decode is that your digest isn't an encoded UTF-8 string but a list of bytes that for all intents and purposes are completely random. You are trying to directly convert the bytes into a string, and doing so is easier if you can assume that they already represent a valid string. With the byte output from a hashing algorithm, though, you cannot safely make such an assumption.
However, if for some reason you still want to use this option, use the second optional parameter for utf8.decode to force it to try and decode the bytes anyway:
final digestString = utf8.decode(bytes, allowMalformed: true);
For reference, a byte list of [1, 255, 47, 143, 6, 80, 33, 202] results in "�/�P!�" where "�" represents an invalid/control character. You do not want to use this option, especially where the string will become part of a URL (as it's virtually guaranteed that the resulting string will not be web-safe).
For the hexadecimal representation of a Digest object, please explicitly call Digest.toString() (though in formatted strings, i.e. "url${digest}", this is done for you implicitly).
I'm frankly not familiar with String.fromCharCode, but I think it's looking for UTF-16 and not UTF-8 bits. I wrote a terminal example to show this, and how the outputs differ.
import 'dart:core';
import 'dart:convert';
import 'package:crypto/crypto.dart';
void main() {
const String password = "mypassword";
// hash the password
var bytes = utf8.encode(password);
var digest = sha256.convert(bytes);
// different formats
var bytesDigest = digest.bytes;
var hexDigest = digest.toString();
String url = "http://example_api.php?hash=";
print(url + hexDigest);
print(url + String.fromCharCodes(bytesDigest));
}
Output:
> dart test.dart
http://example_api.php?hash=89e01536ac207279409d4de1e5253e01f4a1769e696db0d6062ca9b8f56767c8
http://example_api.php?hash=à6¬ ry#Ö,©¸õggÈ
I'm after a way to generate a common secret using the secp256k1 EC. I tried with https://github.com/soyersoyer/SwCrypt/ but doesn't support the secp256k1 curve.
I would need to do something like this:
let pairOne = generateKeyPair()
let pairTwo = generateKeyPair()
let sharedOne = computeSharedSecret(privateKey: pairOne.privateKey, publicKey: pairTwo.publicKey)
let sharedTwo = computeSharedSecret(privateKey: pairTwo.privateKey, publicKey: pairOne.publicKey)
XCTAssertEqual(sharedOne, sharedTwo)
Do you know any library to do it?
I was to trying encrypt a text using CryptoSwift for ios application, and CryptoJS for web application, which has to be decrypted in Java platform. I could able to encrypt successfully in javascript by using the following code.
var message = "Hello"
var password = "samplepasswordky"
function encrypt(message, password) {
var salt = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
var key = CryptoJS.PBKDF2(pass, salt, {
keySize: keySize/32,
iterations: iterations
});
var iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
var encrypted = CryptoJS.AES.encrypt(msg, key, {
iv: iv
});
var encryptedMessage = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
return encryptedMessage;
}
For the same in CryptoSwift I am doing the following, but I could not decrypt the text in Java.
let salt: [UInt8] = Array("0000000000000000".utf8)
let password: [UInt8] = Array("samplepasswordky".utf8)
let iv: [UInt8] = Array("0000000000000000".utf8)
let derivedKey = try! PKCS5.PBKDF2(password: password, salt: salt , iterations: 100, keyLength: 16, variant: .sha1).calculate()
let encrypted = try! AES(key: derivedKey, blockMode: CBC(iv: iv), padding: .pkcs5).encrypt(input)
print(encrypted.toHexString())
Kindly help me to make this work.
This line:
var salt = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
Is not the same as this line:
let salt: [UInt8] = Array("0000000000000000".utf8)
The utf8 encoding of "0000000000000000" is, in hex, 30303030303030303030303030303030 (0x30 is the UTF-8 encoding of the character "0").
What you meant to use here is Array(repeating: UInt8(0), count: 16).
You're also outputting a Base64 string in JavaScript, and a hex string in Swift, which are not the same things.
Unrelated side-note:
This implementation is working pretty hard to get little security. If your password is static, you could do much better by using a random key (i.e. 32 completely random bytes 0-255, not a string of characters). PKBDF2 isn't really buying you much here, excepting slowing down the system (not slowing down the attacker; just your app). Adding a random IV would significantly improve this system as well with little cost.