본문 바로가기
안드로이드 코틀린

[Kotlin][Android] 비밀번호 hash 암호화하기

by teamnova 2022. 1. 5.

안녕하세요 :)

 

이번에는 안드로이드에서 비밀번호를 hash 암호화 하는 방법에 대해 알아보겠습니다. 

아래에 예제가 포함되어 설명되긴 하지만,

좀더 손쉽게 사용가능한 방법으로 스틱코드 extension을 IDE에서 사용하신다면,

해당 링크의 포스트 글을 즐겨찾기 하시는 것으로 손쉽게 코드를 사용하실 수 있습니다.

https://stickode.com/detail.html?no=2711

 

스틱코드

 

stickode.com

 

단방향 해시 함수란?

단방향 해시 함수는 수학적인 연산을 통해 원본 메시지를 변화화여 암호화된 메시지인 다이제스트(digest)를 생성하는 함수를 뜻합니다. 

원본 메시지를 알면 암호화된 메시지를 구할수 있지만, 반대인 암호화된 메시지로 원본 메시지를 구할 수 없기 때문에 '단방향' 이라고 부릅니다.

 

이런 알고리즘에는 여러가지가 존재하는데 

  • SHA
  • MD
  • HAS

이중 가장 대표적인 해시 알고리즘은 SHA-256입니다.

이후에는 예제를 보면서 설명하겠습니다.

 

예제 코드

MainActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        //layout 에서 파싱
        var pwdEt = findViewById<EditText>(R.id.pwd_et)
        var pwdToHashBtn = findViewById<Button>(R.id.pwd_hash_btn)
        var digestTv = findViewById<TextView>(R.id.digest_tv)

        //버튼 클릭 이벤트 리스너 등록
        pwdToHashBtn.setOnClickListener {
            var pwd = pwdEt.text.toString()

            //string null, empty 체크 -> 만약 비었다면 함수 종료함
            if(pwd.isEmpty()){
                return@setOnClickListener //함수 종료
            }

            pwd = getHash(pwd) // pwd를 암호화함
            digestTv.text = pwd //암호화된 pwd 를 textView 에 출력

        }
    }

	// *** 스틱코드 등록 코드 ***
    fun getHash(str: String): String {
        var digest: String = ""
        digest = try {

            //암호화
            val sh = MessageDigest.getInstance("SHA-256") // SHA-256 해시함수를 사용
            sh.update(str.toByteArray()) // str의 문자열을 해싱하여 sh에 저장
            val byteData = sh.digest() // sh 객체의 다이제스트를 얻는다.


            //얻은 결과를 hex string으로 변환
            val hexChars = "0123456789ABCDEF"
            val hex = CharArray(byteData.size * 2)
            for (i in byteData.indices) {
                val v = byteData[i].toInt() and 0xff
                hex[i * 2] = hexChars[v shr 4]
                hex[i * 2 + 1] = hexChars[v and 0xf]
            }

            String(hex) //최종 결과를 String 으로 변환

        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
            "" //오류 뜰경우 stirng은 blank값임
        }
        return digest
    }
	// *** 스틱코드 등록 코드 ***
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/pwd_et"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:hint="비밀번호 입력하기"
        android:inputType="textPersonName"
        android:minWidth="290dp"
        android:minHeight="48dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="암호화된 비밀번호"
        android:textColor="@color/black"
        android:textSize="16sp"
        app:layout_constraintStart_toStartOf="@+id/pwd_et"
        app:layout_constraintTop_toBottomOf="@+id/pwd_hash_btn" />

    <Button
        android:id="@+id/pwd_hash_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp"
        android:text="비밀번호\n암호화 하기"
        app:layout_constraintEnd_toEndOf="@+id/pwd_et"
        app:layout_constraintStart_toStartOf="@+id/pwd_et"
        app:layout_constraintTop_toBottomOf="@+id/pwd_et" />

    <TextView
        android:id="@+id/digest_tv"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        app:layout_constraintEnd_toEndOf="@+id/pwd_et"
        app:layout_constraintStart_toStartOf="@+id/pwd_et"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>

예제 시현