본문 바로가기

3.구현/HTML5&Javascript

[javascript] Javascript에서 MD5 사용

들어가기

Javascript에서 MD5 라이브러리들을 간단하게 살펴보고 테스트를 해보았다.

작성자: ospace114@empal.com, http://ospace.tistory.com/

기존 문제점

기존에 MD5을 이용해 해시값을 생성하는데 있어서 이슈가 있다.

SparkMD5 성능 이슈

기존에 SparkMD5 라이브러리를 사용해 MD5 해시값을 생성하고 있었다.

<script src="spark-md5.js"></script>
<script>
  var hash = SparkMD5.hash(“hello world”);
  console.log(hash);
  //MD5: 5eb63bbbe01eeed093cb22bb8f5acdc3
</script>

잘 사용하고 있었는데 문제점이 파일 크기가 커지만 시간이 오래걸린다. 파일 크기가 4MB와 16MB인 경우 각각 0.58초와 2초가 걸린다. 파일 개수가 많아지면 치명적이게 된다.

IE11 문제점

더 큰 문제는 IE11에서는 Chrome에서 파일 읽어 오는 부분이 다르다. IE11에서는 readAsBinaryString()이 지원하지 않는다. IE12에서는 지원하고 있다. 참고로 mdn에 의하면 이 함수는 더 이상 추천하지 않는 기능이다. SparkMD5 라이브러리가 IE11에서 호환 문제가 있다.

var reader = new FileReader();
reader.onload = funciton() {
    var hash = SparkMD5.hash(reader.result);
    //…
};
reader.readAsBinaryString(file);

이젠 IE12로 강제하기 때문에 이 문제는 더이상 문제가 아닐 수 있다.

readAsBinaryString 함수로 대처

readAsBinaryString()을 사용해서 스트링으로 변환 해서 처리하는 방안도 고려해보았다. String.fromCharCode.apply()을 사용할 경우 스택오법플로우로 처리가 불가했고, String.fromCharCode()를 사용해 루프로 처리할 경우 성능 상에 문제가 있었다.

그래서 SparkMD5 라이브러리를 대처할 만한 라이브러리를 찾자.

MD5 라이브러리

간단히 검색해서 찾은 MD5 라이브러리는 다음과 같다. (2024/01/19 기준)

이름 URL 라이센스 크기(full/minified)
blueimpMD5 https://github.com/blueimp/JavaScript-MD5 MIT License 11.5k/3.7k
FastMD5 https://github.com/xibre/FastMD5 MIT License 8.3k/5.1k
jsHashes https://github.com/h2non/jshashes BSD-3-Clasuse License 59.6k/23.8k
js-md5 https://github.com/emn178/js-md5 MIT License 29.4k/10.4k
sparkMD5 https://github.com/satazor/js-spark-md5 WTFPL License 22.9k/10.1k

FastMD5은 github에서 사라졋다. ㅡ.ㅡ;;;

blueimMD5는 MD5에 대한 해시값을 hex와 hamc 형태로 제공한다. 파일 크기도 가장작다. blueimpMD5 사용법이다.

let res = md5("Hello world!");
console.log(res); // 86fb269d190d2c85f6e0468ceca42a20

jsHashes는 기능적으로 가장 풍부하다. MD5, SHA1, SHA256, SHA512, HMAC, RIPEMD-160을 지원하한다. 대신에 파일 크기가 가장 크다. jsHashes 사용법이다.

const MD5 = new Hashes.MD5();
let res = MD5.hex("Hello world!");
console.log(res); // 86fb269d190d2c85f6e0468ceca42a20

js-md5는 MD5에 대한 해시값을 제공한다. js-md5 사용법이다.

let res = md5("Hello world!");
console.log(res); // 86fb269d190d2c85f6e0468ceca42a20

sparkMD5는 MD5에 대한 해시값을 제공한다. sparkMD5 사용법이다.

let res = SparkMD5.hash("Hello world!");
console.log(res); // 86fb269d190d2c85f6e0468ceca42a20

테스트

실제 파일을 이용해 테스트를 진행해보았다. 파일 크기는 약 10.4MB이다. 실행코드에서 sparkMD5만 사용법이 달랐다.

let data = ...;
let spark = new SparkMD5.ArrayBuffer();
spark.append(data);
let res = spark.end();
console.log(res);

다음은 테스트한 결과이다.

이름 해시값 소요시간(msec)
blueimpMD5 060e4e9e30bcb9ae675a80328a87a687 0.08
jsHashes d41d8cd98f00b204e9800998ecf8427e 0.12
js-md5 e79a13311cda6f6abb30b5735bbf23fb 71.86
sparkMD5 e79a13311cda6f6abb30b5735bbf23fb 159.40

blueimpMD5와 jsHashes의 해시값이 각자 다르다. 혹시나 해서 MD5 확인하는 사이트에서 재확인해보았다.

확인한 해시값은 “e79a13311cda6f6abb30b5735bbf23fb”으로 js-md5와 spartkMD5와 동일하다.

결론

blueimpMD5와 jsHashes은 문자열일 경우 MD5 해시값이 제대로 나왔는데 파일은 전혀 다르게 나았고 소요시간도 이상하게도 너무 짧아보였다. blueimpMD5와 jsHashes는 문자열만 가능한 것으로 보이며, 제대로 해시값이 생성되지 않았기에 소요시간도 짧게 나온게 아닌가라는 생각이 든다. URL 주소에 문서상으로 문자열을 인자로 사용하다고 되어 있고 파일에 대한 부분은 따로 언급이 없다. 물론 정확한 내용은 더 분석을 해봐야하지만 시간이 오래걸려보여서 생략했다. 결국 blueimpMD5와 jsHashes는 파일에 대한 MD5 해시값 생성에는 적합하지 않았다라고 판단이 된다. 결국, sparkMD5에 대안으로는 js-md5가 적합하다고 결론을 내렸다.

부족한 글이지만 여러분에게 도움이 되었으면 하네요. 모두 즐거운 코딩생활하세요. ^^ ospace.

참고

[1] blueimpMD5, https://github.com/blueimp/JavaScript-MD5
[2] FastMD5, https://github.com/xibre/FastMD5
[3] jsHashes, https://github.com/h2non/jshashes
[4] js-md5, https://github.com/emn178/js-md5
[5] sparkMD5, https://github.com/satazor/js-spark-md5

반응형