AW202: ButterKnife, Certificate Pinning 등

Android Weekly는 매주 발행되는 안드로이드 뉴스레터입니다. 영어 기사를 정독할 시간이 없는 분을 위해 핵심 꼭지를 요약했습니다.

주간 안드로이드 뉴스를 요약해 드립니다. Android Weekly 202 원문도 읽어보세요.


버터나이프 제대로 알고 쓰기

  • 버터나이프는 많은 개발자들이 즐겨 사용하는 대표적인 뷰 인젝션 라이브러리죠. 버터나이프에 대해 더 알아보기 (Get more out of Butter Knife)에서 저자는 그 많은 개발자들이 단지 @Bind, @OnClick 어노테이션 정도만 사용하는데 그치는 것이 안타까웠던 것 같습니다. 버터나이프의 더 많은 특징과 기능을 소개합니다.

//dependency 설정
compile 'com.jakewharton:butterknife:7.0.1'
  • 일반 사용법: @Bind, @OnClick
class LetsNurtureDemoActivity extends Activity {
  @Bind(R.id.edUserName) EditText edUserName;
  @Bind(R.id.edPassword) EditText edPassword;
  @Bind(R.id.instructions) TextView txtInstructions;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.demo_activity);
    ButterKnife.bind(this);
  } 
  @OnClick(R.id.btnLogin)
  public void btnLoginClick(View view) { 
    .....
    .....
    .....
   }
}

이런 개발 뉴스를 더 만나보세요

  • 더 많은 기능 사용하기

한번에 여러 뷰에 리스너 설정하기

@OnClick({ R.id.button1, R.id.button2, R.id.button2 })
public void buttonClicks(View view) {
    switch(view.getId()) {
        case R.id.button1:
            Toast.makeText(this, "Button1 clicked!", LENGTH_SHORT).show();
            break;
        case R.id.button1:
          Toast.makeText(this, "Button2 Clicked!", LENGTH_SHORT).show();           
          break;
        case R.id.button1:
          Toast.makeText(this, "Button3 clicked!", LENGTH_SHORT).show();
          break;
    }
}

다양한 리스너 종류

  • @OnLongClick
  • @OnPageChange OnPageChange.Callback
  • @OnTextChanged OnTextChanged.Callback
  • @OnTouch
  • @OnItemLongClick
  • @OnCheckedChanged

바인드 리소스: color, dimen, string, drawable 등 다양하게 사용 가능 합니다!

class ExampleActivity extends Activity {
 @BindColor(R.color.red) int red; 
  @BindString(R.string.activity_title) String activityTitle;
   @BindDimen(R.dimen.btn_horizontal_margin_common) Float btnHorizontalMarginCommon;
  @BindDrawable(R.drawable.ic_instructions) Drawable iconInstructions;
}

리스트나 어레이의 여러 뷰 처리하기

Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
//Action and Setter
static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
  @Override public void apply(View view, int index) {
    view.setEnabled(false);
  }
};
 
static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
  @Override public void set(View view, Boolean value, int index) {
    view.setEnabled(value);
  }
};

뷰 속성 설정하기

ButterKnife.apply(nameViews, View.ALPHA, 0.0f);

ButterKnife.findById 사용하기: 바로 형변환이 되어 편리합니다!

View view = LayoutInflater.from(context).inflate(R.layout.thing, null);
TextView firstName = ButterKnife.findById(view, R.id.first_name);
TextView lastName = ButterKnife.findById(view, R.id.last_name);
ImageView photo = ButterKnife.findById(view, R.id.photo);

@Nullable: 타겟을 찾을 수 없다면 exception 던지도록

@Nullable  @Bind(R.id.edUserName) 
EditText edUserName;

더 안전한 https통신을 위한 팁

안드로이드/자바 앱에서 https 안전하게 사용하기 (Protecting https for Android/Java apps )에서 https통신과 관련한 3가지 팁을 드립니다.

  • 시스템 인증서(system certificate) 사용에서 벗어나기

    • OS에 설치된 certificate은 China Internet Network Information Center 와 같은 root CAs를 포함하고 있을 것입니다. 다시 말하면 이런 CA들은 어쩌면 은밀히 MiTM 공격을 하거나 request나 response가 노출 또는 수정될 수 있다는 의미입니다.

    • 안드로이드 OS는 200개 이상의 root CAs를 가지고 있고, 제조사들은 그들대로 또 추가 인증서를 넣습니다. 우리 이거 믿어도 될까요?? Lenovo는 써드파티 root CA 인증서를 랩탑에 심었다가 개인키(private key)가 노출되기도 했습니다.

    • 또 다른 시스템 certificate의 문제는 rootCAs 인증서 업데이트가 안드로이드 OS업데이트에 의존적이라는 것입니다. 만약 root CA들 중 몇 개가 해킹되어 개인키가 노출되었다면 global/personal MiTM에 사용될 수 있고, 이를 막을 수 없는 사태가 옵니다.

    • 자 그럼 어떻게 해결하면 좋을까요? Google은 Google Internet Authority G2 프로젝트를 제공합니다. 여러분 앱에 함께 포함해 어떤 인증서를 신뢰할 수 있는지 여부에 따라 통제할 수 있습니다.

  • Certificate Pinning 사용 고려하기

    • 간단히 말하면 certificate pinning은 어떤 CA들를 신뢰하고 또 포함되기로 기대되는 certificate을 포함하는 host에 연결하도록 인증서 체인을 체크하는 룰을 갖는 것을 의미합니다.

    • 시큐어 소켓 커넥션 체킹의 순서는 아래와 같습니다. - Socket관련한 작업들 - 인증서 체인은 TrustManager를 통해 믿을 수 있는지 여부를 가름(믿을 수 있다는 것은 신뢰할 수 있는 CA들이거나 또는 OS에 직접 인스톨 된 인증서라는 것) - 오직 TrustManager를 통해 신뢰할 수 있다고 판단된 인증서만이 추가적인 Certificate Pinning단계를 거침
    • 위 절차에서 보듯이 certificate pinning없이는 어떤 인증서라도 ‘신뢰할 수’ 있는 CA들로부터 생성된 인증서로 간주되어 MiTM에 악용될 수 있는 위헙이 있습니다.

    • 상황 하나를 가정해 보자구요, 여러분은 China Internet Network Information Center 등으로 부터 MiTM을 막고 싶고, 보통의 SSL/TLS certificate을 가지고 있습니다.

    • certificatePinner.add("api.myhost.com", "sha256/fingerPrintOfTheCertificateThatYouTrust")를 추가해서 체인 중 적어도 하나의 인증서가 당신이 신뢰할 수 있는 인증서가 될 수 있도록 만들고 MiTM에 개인키를 빼앗기는 유일한 방법이 됩니다. 일반적으로 체인을 날조하거나 신뢰할 수 있는 인증서를 포함시키는 것이 아주 어렵거나 거의 불가능합니다.

    “따라서 한 도메인에 여러개의 지문을 남겨서 안전성을 높일 수 있습니다.”

    • 인증서 피닝이 작동하는지 알았다면 여러분은 이 방법이 안전성을 높이는 것 뿐만 아니라 여러분 앱의 오래된 버전을 멈추게 한다는 것도 이해할 수 있을 것입니다.

    • 백엔드 관리자에게 고지없이 인증서 피닝을 하는 것을 주의하세요! 많은 앱에서는 그만한 가치가 없다고 생각해서 이를 하지 않습니다만 개인 정보, 사업자 정보 등 기밀사항을 전달하는 앱이라면 문제가 발생하기 전 사용자에게 업데이트를 강제하는 것이 바람직합니다.

    • 참고 정보로 새로운 인증서를 준비한다면 CertificatePinner에 새 인증서 fingerPrint만 추가하는 것으로 서버사이드에서 실제 전환을 하기 전에 미리 준비해 놓을 수 있습니다.

  • HTTPS를 위해 라이브러리 종류

    • HttpUrlConnection이나 Apache HTTP Client는 사용하지 마세요!! 왜냐하면 이것들은 JDK와 의존적이라 라이브러리에서 버그가 발견되어도 OS업데이트가 되기 전까지 고칠 수 없다는 문제가 있습니다.

    • OkHttp를 사용하세요. OS업데이트에 의존하지 않고 업데이트 할 수 있고, securing https connections를 위한 모든 것- SSLSocketFactory, CertificatePinner 을 포함하고 있습니다.

오픈소스 라이브러리

  • PowerfulRecyclerViewAdapter 어떤 종류의 아이템 리스트를 지원해주는 RecyclerView.Adapter입니다.

  • Conductor View-based 안드로이드 앱 개발을 가능게 하는 프레임워크입니다. 표준 안드로이드 뷰에 대해 랩퍼를 제공해주는, 작지만 갖출 것은 갖춘 실속있는 프레임워크입니다.

  • f8app F8 -2016년도의 전제 소스코드입니다.

더 읽을 거리

4월 넷째 주의 기사를 Android Weekly 202 영어 원문에서 볼 수 있습니다.

지난 뉴스가 궁금하다면 아래 링크를 참고해 주세요.

컨텐츠에 대하여

이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.


Realm Korea

Realm Korea Team

4 design patterns for a RESTless mobile integration »

close