備忘録

備忘録

自作PCを作るときにおすすめなサイト

Ⅰ. はじめに

基本的に、自作PCを作るときはパーツのリストを作ってから購入に踏み切ると思います。
その時のリスト作りに役立つWEBサイトの紹介です。

pcpartpicker.com


https://pcpartpicker.com/list/

作ったリストの消費電力まで計算してくれる優秀なサイトです。

価格.com ピックアップリスト


http://kakaku.com/pickuplist/

日本人に人気のサイトです。
作ったリストに対するアドバイスが得られる場合があります。

Steamハードウェア&ソフトウェア 調査

https://store.steampowered.com/hwsurvey/Steam-Hardware-Software-Survey-Welcome-to-Steam

Steamユーザの統計情報を得る事が出来ます。

JavaでJSONを扱う(GSONの使い方)

Ⅰ. はじめに

JavaJSONを扱う方法です
最近人気のGoogleが開発しているライブラリ GSON を利用します。

C#の場合はJSON.NETを利用すれば、クラスを作らなくてもJSONをdynamicに利用したり、LINQ to Objects ができますが、GSONはクラスが必須です。
※2018/03/24追記
GSONでもクラスが不要な書き方がサポートされていました。

この記事で利用するサンプルのJSON

[
  {"id": 1, "name": "name001", "age": 20},
  {"id": 2, "name": "name002", "age": 21},
  {"id": 3, "name": "name003", "age": 22}
]

Ⅱ. 使い方(クラスを作る場合)

1. JSONJavaのクラスに変換する

手動での変換が面倒な場合は以下のようなWebサイトを利用します。
http://www.jsonschema2pojo.org/
f:id:kagasu:20170310171151p:plain

2. Main.java

String strJson = "[{\"id\": 1, \"name\": \"name001\", \"age\": 20},{\"id\": 2, \"name\": \"name002\", \"age\": 21},{\"id\": 3, \"name\": \"name003\", \"age\": 22}]";

Gson gson = new Gson();
User[] users = gson.fromJson(strJson, User[].class);

for(User user : users) {
	System.out.println(user.name);
}

3. 実行結果

name001
name002
name003

Ⅲ. 使い方(クラスを作らない場合)

1. Main.java
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

public class Main {
    public static void main(String[] args){
        String strJson = "[{\"id\": 1, \"name\": \"name001\", \"age\": 20},{\"id\": 2, \"name\": \"name002\", \"age\": 21},{\"id\": 3, \"name\": \"name003\", \"age\": 22}]";

        JsonParser parser = new JsonParser();
        JsonArray objs = parser.parse(strJson).getAsJsonArray();

        for(JsonElement obj : objs) {
            System.out.println(obj.getAsJsonObject().get("name").getAsString());
        }
    }
}

3. 実行結果

name001
name002
name003

Javaでokhttpを使って全ての証明書を許可する

Ⅰ. はじめに

オレオレ証明書などは以下のエラーを吐いて弾かれてしまいます。
デバッグ時など、とりあえず全部許可したいときのやり方です。

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.
ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

Ⅱ. プログラム

import okhttp3.*;

import javax.net.ssl.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Main {

  static class MyX509TrustManager implements X509TrustManager {
    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
      return new java.security.cert.X509Certificate[]{};
    }
  }

  private static String okHttpGet() throws Exception {
    // リクエストを作成する
    Request request = new Request.Builder()
        .url("https://example.com/")
        .get()
        .build();

    // OkHttpClient の Bulider を作成する
    OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

    // proxyを設定する
    clientBuilder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8008)));
    
    // MyX509TrustManager を割り当てる
    // MyX509TrustManager は全ての証明書を許可するようにしている
    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, new TrustManager[] { new MyX509TrustManager() }, new java.security.SecureRandom());
    clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), new MyX509TrustManager());

    OkHttpClient client = clientBuilder.build();

    // GET する
    Response response = client.newCall(request).execute();
    return response.body().string();
  }

  public static void main(String[] args) throws Exception{
    String str = okHttpGet();
    System.out.println(str);
  }
}

C#でPublic Key Pinningする

Ⅰ. はじめに

Public Key Pinningとは、SSL証明書のチェックを行うことです。
チェックを行うことで、不正な証明書を検知することができます。

例えばクラッカーはMITMを利用して傍受を試みます。
MITMを利用するとSSL証明書が書き換わる為、
不正な証明書であれば通信を行わないようにすることが出来ます。

Ⅱ. プログラム

Program.cs
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);
CertificateValidation.cs
public static bool OnRemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
  var hashs = new Dictionary<string, string>()
  {
    { "aaa.jp", "6c276e0c4e2fa19d1656df1298d8ff6497d0cc49" },
    { "aab.jp", "7dfc0fd1abf2af11dd2f9503448009f090d529eb" },
    { "aac.jp", "bb1d931851cc679a476021494550573eb1e1148d" }
  };

  if (hashs.ContainsValue(certificate.GetCertHashString().ToLower()))
  {
    // 通信を許可する
    return true;
  }
  else
  {
    // 通信を許可しない
    return false;
  }
}

SSL証明書ハッシュ値は、SSL証明書の「拇印」の値を使います
f:id:kagasu:20170310145511p:plain

「拇印」のコピーについて

「拇印」をそのままコピーするとデータ先頭に謎のデータが付加されています。
テキストエディタやVisualStudioのエディタで見ても見た目は正しい文字列ですが、バイナリで見ると間違っていることが解ります。
面倒ですがコピーしない方が良いです。
f:id:kagasu:20170915111229p:plain

注意

証明書の有効期限を予め確認する必要があります。
上記のサンプルコードの場合、証明書を更新した後にクライアント側を修正しようとしても通信が一切できない状態になります。
アップデートチェックとしてWeb APIを利用しているケースでは致命的になる場合があります。

PythonでPOSTする

Ⅰ. はじめに

PythonでPOSTする方法です。

Ⅱ. プログラム

import requests

# InsecureRequestWarning を非表示にする場合
# from requests.packages.urllib3.exceptions import InsecureRequestWarning
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

s = requests.session()

proxies = {
  'http':'http://user:pass@127.0.0.1:8008',
  'https':'https://127.0.0.1:8008'
}

headers = {
  'User-Agent' : 'Mozilla/...',
  # 'Content-Type' : 'application/x-www-form-urlencoded'
}

params = {
  'param1' : 'xxx',
  'param2' : 'yyy'
}

s.proxies = proxies
# 証明書チェックを省く
s.verify = False
s.headers = headers

response = s.post('https://example.com/', params)

# 文字化けする場合はcmdで「chcp 65001」を実行すると治る(Windows)
# 65001 はutf-8
print response.content

Ⅲ. その他

開発環境でMITMを利用したproxy(FiddlerやBurpSuiteやCharlesやmitmproxyなど)
SSL Decryptを有効にしていると以下のエラーが出ます。

requests.exceptions.SSLError:
("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)
s.verify = False

にするとでなくなります。