3

In Java, I used this:

public void encryptData() {
    String data = "Hello World";
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    if (md == null) {
        return;
    }
    md.update(data.getBytes());
    String dataEncoded = Base64.encodeToString(md.digest(), 11);
    return dataEncoded; //print: sQqNsWTgdUEFt6mb5y4_5Q
}

How do I do have the same results in Swift?

Updated:

func test() -> Void {
    var data: String = "Hello World"
    data = md5(data)
    data = base64Encode(data)
    print("data = \(data)") //YjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTU= 
}

md5 and base64Encode function used from md5 here and base64 here

Any hints will be helpful.

Community
  • 1
  • 1
Nguyen Hung
  • 113
  • 2
  • 7
  • A MD5 function is for example here: http://stackoverflow.com/questions/32163848/how-to-convert-string-to-md5-hash-using-ios-swift, and Base64 here: http://stackoverflow.com/questions/34406024/swift-base64-format. You can easily find more by searching for `[swift] md5` or `[swift] base64`. – Btw, MD5 is *not* an encryption. – Martin R Sep 07 '16 at 11:42
  • I tried md5 and base64 but the result is different in java. Result is: YjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTU= – Nguyen Hung Sep 07 '16 at 15:09
  • Show what you tried. Input, output, and expected output. We cannot guess what you did wrong. – Martin R Sep 07 '16 at 15:46
  • Please update the *question* with your code. – Martin R Sep 07 '16 at 16:49
  • Thank you so much. I've updated my code. – Nguyen Hung Sep 07 '16 at 17:20
  • hello, how can i get SHA through cmd for Android? i used command line (cmd) but got me wrong ssh1. keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64 – Vrajesh Mar 09 '21 at 07:10

1 Answers1

1

Your code does not produce the expected result because the referenced md5() function returns the message digest as a hex-encoded string, which is then Base64 encoded. So instead of

 String -> UTF-8 data -> MD5 digest -> Base64 encoding

you are doing

 String -> UTF-8 data -> MD5 digest -> hex encoding -> Base64 encoding

A small modification of the function returns the message digest as data:

func md5(string string: String) -> NSData {
    var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
    let data = string.dataUsingEncoding(NSUTF8StringEncoding)! // Conversion to UTF-8 cannot fail
    CC_MD5(data.bytes, CC_LONG(data.length), &digest)
    return NSData(bytes: digest, length: digest.count)
}

Now you can compute the Base 64 encoded MD5 digest:

let string = "Hello World"

// Compute MD5 message digest:
let md5data = md5(string: string)
print("md5data = \(md5data)") // md5data = <b10a8db1 64e07541 05b7a99b e72e3fe5>

// Convert to Base 64 encoded string:
let base64 = md5data.base64EncodedStringWithOptions([])
print("base64 = \(base64)") // base64 = sQqNsWTgdUEFt6mb5y4/5Q==

This is almost what you expect. The Java code apparently produces the so-called "base64url" variant without padding (compare https://en.wikipedia.org/wiki/Base64#Variants_summary_table).

Therefore we have to modify two characters and remove the padding:

let base64url = base64
    .stringByReplacingOccurrencesOfString("+", withString: "-")
    .stringByReplacingOccurrencesOfString("/", withString: "_")
    .stringByReplacingOccurrencesOfString("=", withString: "")
print("base64url = \(base64url)") // base64url = sQqNsWTgdUEFt6mb5y4_5Q

Now the result is sQqNsWTgdUEFt6mb5y4_5Q, and identical to what you got from the Java code.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382