We consider a system where each user has a public key and a private key. In this system, a certificate is a data item that is issued by one user u and contains the public key of another user v. A third user w that knows the public key of u can verify that this certificate has not been corrupted (by an adversary) since it was issued by u, and so can accept the public key in the certificate as the correct public key of v. User w can use this accepted public key of v in two ways. First, w can securely communicate with v. Second, w can obtain more public keys of other users, as it used the public key of u to obtain the public key of v. However, the safety of the second use is questionable if u, the issuer of the certificate, has concluded that it cannot trust v enough to accept a public key merely because v accepts it. To solve this problem, we propose that each certificate should have a "rating". The rating of a certificate describes how much trust the issuer puts on the subject concerning key acceptance. We present an algorithm for computing a subgraph G.dst(src) of a certificate graph G, for a user src to find the correct public key of another user dst in G. The time complexity of this algorithm is 0(e), where e is the number of certificates in the system. This algorithm meets the lower bound of the worst case complexity.