SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

ASP.NETを使ってランダムなパスワードを生成する

ASP.NET 2.0のGeneratePassword()メソッドをASP.NET 1.xで利用する方法

さらに強力なランダムパスワードジェネレータ

 GUIDを使ってランダムなパスワードを生成する方法の良いところは、実現するのも使用するのも簡単なことです。しかし出力される結果をコントロールできない上に、英数字(しかも文字はaからfまで)のパスワードしか生成することができません。セキュリティのガイドラインを適用するために、アルファベット以外の文字を何文字か使用したパスワードや、広い範囲の文字(アルファベット全部など)を使ったパスワードなどが必要になったとしても、対応することができません。また、何らかの理由で数字を使わないパスワードが必要になった場合や、パスワードの大文字と小文字を区別したくなった場合にも同じことが言えます(前述のGUIDを使った方法では6文字しか使えず、しかもすべて小文字です)。

 より堅牢な方法を実現するには、GeneratePassword(length, numberOfNonAlphanumericCharacters)というパスワードジェネレータを作ります。このパスワードジェネレータでは、ASP.NET 2.0のMembership APIに含まれている同名のメソッドと同等の機能を再現します(このメソッドは、ASP.NET 2.0を使っているのであればぜひ使いたいメソッドであり、パスワードの長さとアルファベット以外の文字の数を指定することができます)。さらに、このパスワードジェネレータは、強力な暗号化機能を持った乱数ジェネレータであるRNGCryptoServiceProviderクラスを使用しています。そのため、このアルゴリズムでは、以前に生成された乱数を基にこれから生成される乱数の予想を立てることは困難です。

 私と同じようにASP.NET 1.xの世界から抜け出せないのであれば、自作のGeneratePassword()メソッドを使わなければなりません。しかし、ASP.NET 2.0と同じものを開発する必要はありません。ASP.NET 2.0のコードを借用すればよいのです。それはReflectorを使えば簡単に実現できます。Membership.GeneratePassword(length, numberOfNonAlphanumericCharacters)のコードを次に示します。ライブデモもご覧ください。

' VB.NET
Function GeneratePassword(ByVal length As Integer, _
        ByVal numberOfNonAlphanumericCharacters As Integer) As String
  'Make sure length and numberOfNonAlphanumericCharacters are valid....
  '... checks omitted for brevity ... see live demo for full code ...
  
  Do While True
    Dim i As Integer
    Dim nonANcount As Integer = 0
    Dim buffer1 As Byte() = New Byte(length  - 1) {}
    
    'chPassword contains the password's characters as it's built up
    Dim chPassword As Char() = New Char(length  - 1) {}
    
    'chPunctionations contains the list of
    'legal non-alphanumeric characters
    Dim chPunctuations as Char() = _
      "!@@$%^^*()_-+=[{]};:>|./?".ToCharArray()

    'Get a cryptographically strong series of bytes
    Dim rng as _
      New System.Security.Cryptography.RNGCryptoServiceProvider
    rng.GetBytes(buffer1)
        
    For i = 0 To length - 1
      'Convert each byte into its representative character
      Dim rndChr As Integer = (buffer1(i) Mod 87)
      If (rndChr < 10) Then
        chPassword(i) = Convert.ToChar(Convert.ToUInt16(48 + rndChr))
      Else
        If (rndChr < 36) Then
          chPassword(i) = _
            Convert.ToChar(Convert.ToUInt16((65 + rndChr) - 10))
        Else
          If (rndChr < 62) Then
            chPassword(i) = _
              Convert.ToChar(Convert.ToUInt16((97 + rndChr) - 36))
          Else
            chPassword(i) = chPunctuations(rndChr - 62)
            nonANcount += 1
          End If
        End If
      End If
    Next
    
    If nonANcount < numberOfNonAlphanumericCharacters Then
      Dim rndNumber As New Random
      For i = 0 To (numberOfNonAlphanumericCharacters - nonANcount) - 1
        Dim passwordPos As Integer
        Do
          passwordPos = rndNumber.Next(0, length)
        Loop While Not Char.IsLetterOrDigit(chPassword(passwordPos))
        chPassword(passwordPos) = _
          chPunctuations(rndNumber.Next(0, chPunctuations.Length))
      Next
    End If
    
    Return New String(chPassword)
  Loop
End Function
 ここではGetPassword()メソッドに変更を加えて、エラーを起こす可能性のある英数字以外の文字(#&)を除外しました。ASP.NET 2.0では、ランダムに生成されたパスワードがクロスサイトスクリプティング攻撃に悪用されないようにチェックしており、<#、および&をチェック対象にしています。このメソッドでは、こうしたチェックをしなくて済むように、単純にこれらの文字を除外しています。

まとめ

 この記事では、ASP.NETを使った2種類のランダムなパスワードの生成方法を取り上げました。1つ目の手法では、GUIDからハイフンを取り除いて最初のlength文字を取得しました。これは手早く簡単にランダムなパスワードを生成する方法です。しかし、使用可能な文字の種類がかなり限られている(aからf、および0から9)ので、複雑なことはできません。

 もっと強力で洗練されたランダムパスワードジェネレータが、ASP.NET 2.0のMembership.GeneratePassword()メソッドです。ASP.NET 2.0を使っているのであれば、このメソッドを使うのがよいでしょう。しかし、まだASP.NET 1.xを使っている場合に、GUIDを使った手法よりも強力なパスワードジェネレータが必要なのであれば、自分で作成する必要があります。そこでReflectorを使ってASP.NET 2.0のGeneratePassword()メソッドを「コピー」する方法を説明しました。

 ぜひ試してみてください。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Scott Mitchell(Scott Mitchell)

http://www.4guysfromrolla.com/ScottMitchell.shtml

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/238 2006/04/11 19:03

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー